{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Add Two Integers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数学"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: sum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #两整数相加"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "给你两个整数&nbsp;<code>num1</code> 和 <code>num2</code>，返回这两个整数的和。\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>num1 = 12, num2 = 5\n",
    "<strong>输出：</strong>17\n",
    "<strong>解释：</strong>num1 是 12，num2 是 5 ，它们的和是 12 + 5 = 17 ，因此返回 17 。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>num1 = -10, num2 = 4\n",
    "<strong>输出：</strong>-6\n",
    "<strong>解释：</strong>num1 + num2 = -6 ，因此返回 -6 。\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>-100 &lt;= num1, num2 &lt;= 100</code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [add-two-integers](https://leetcode.cn/problems/add-two-integers/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [add-two-integers](https://leetcode.cn/problems/add-two-integers/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['12\\n5', '-10\\n4']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        finalCnt.insert(0,0)\n",
    "        n = len(finalCnt)\n",
    "        x = [0] * n\n",
    "        x[0] = 1\n",
    "        adj = [list() for i in range(n)]\n",
    "        for u,v in edges:\n",
    "            adj[u].append(v)\n",
    "            adj[v].append(u)\n",
    "        for num,idx in plans[::-1]:\n",
    "            if num == 1:\n",
    "                finalCnt[idx] *= 2\n",
    "                x[idx] *= 2\n",
    "            elif num == 2:\n",
    "                for v in adj[idx]:\n",
    "                    finalCnt[v] -= finalCnt[idx]\n",
    "                    x[v] -= x[idx]\n",
    "            else:\n",
    "                for v in adj[idx]:\n",
    "                    finalCnt[v] += finalCnt[idx]\n",
    "                    x[v] += x[idx]\n",
    "        zero_end = (totalNum - sum(finalCnt)) // sum(x)\n",
    "        for i in range(n):\n",
    "            finalCnt[i] += x[i] * zero_end\n",
    "        return finalCnt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        n = len(finalCnt) + 1\n",
    "        g = [[] for _ in range(n)]  # 建图\n",
    "        for u, v in edges:\n",
    "            g[u].append(v)\n",
    "            g[v].append(u)\n",
    "\n",
    "        # final count of all n vertices\n",
    "        # initialize the final count of vertice 0 as complex number 1j\n",
    "        cnt = [0+1j] + finalCnt\n",
    "\n",
    "        # reverse simulation\n",
    "        for num, idx in plans[::-1]:\n",
    "            # option1: halve the number of volunteers\n",
    "            if num == 1:\n",
    "                cnt[idx] *= 2\n",
    "            # option2: adding the number of volunteers\n",
    "            elif num == 2:\n",
    "                for neighbor in g[idx]:\n",
    "                    cnt[neighbor] -= cnt[idx]\n",
    "            # option3: substracting the number of volunteers\n",
    "            else:\n",
    "                for neighbor in g[idx]:\n",
    "                    cnt[neighbor] += cnt[idx]\n",
    "        \n",
    "        s = sum(cnt)\n",
    "\n",
    "        # initial number of volunteers at vertex 0\n",
    "        initial0 = (totalNum - s.real) // s.imag\n",
    "\n",
    "        # final number of volunteers at each vertex\n",
    "        ans = [int(x.real + x.imag * initial0) for x in cnt]\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        firstNumList = [1] + [0] * len(finalCnt)\n",
    "        originCnt = [0] + finalCnt\n",
    "        table = [[] for _ in range(len(firstNumList))]\n",
    "        plan_fun = []\n",
    "        def method1(idx):\n",
    "            originCnt[idx] *= 2\n",
    "            firstNumList[idx] *= 2\n",
    "        def method2(idx):\n",
    "            for i in table[idx]:\n",
    "                originCnt[i] -= originCnt[idx]\n",
    "                firstNumList[i] -= firstNumList[idx]\n",
    "        def method3(idx):\n",
    "            for i in table[idx]:\n",
    "                originCnt[i] += originCnt[idx]\n",
    "                firstNumList[i] += firstNumList[idx]\n",
    "        plan_fun = (0, method1, method2, method3)\n",
    "        for edge in edges:\n",
    "            table[edge[0]].append(edge[1])\n",
    "            table[edge[1]].append(edge[0])\n",
    "        for i in range(len(plans) - 1, -1, -1):\n",
    "            plan = plans[i]\n",
    "            plan_fun[plan[0]](plan[1])\n",
    "        rate = sum(firstNumList)\n",
    "        first_num = (totalNum - sum(originCnt)) // rate\n",
    "        for i in range(len(originCnt)):\n",
    "            originCnt[i] += firstNumList[i] * first_num\n",
    "        return originCnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        fn = [1] + [0]*len(finalCnt)\n",
    "        finalCnt = [0]+finalCnt\n",
    "        # 初始化两个数组\n",
    "        # 操作均为线性\n",
    "        dic=collections.defaultdict(list)\n",
    "        for e in edges:\n",
    "            u,v=e[0],e[1]\n",
    "            dic[u].append(v)\n",
    "            dic[v].append(u)\n",
    "        # 建立场馆之间的连接\n",
    "        for i in range(len(plans)-1,-1,-1):\n",
    "            num = plans[i][0]\n",
    "            ids = plans[i][1]\n",
    "            arr = dic[ids]\n",
    "            if num == 3:\n",
    "                for j in arr:\n",
    "                    fn[j]+=fn[ids]\n",
    "                    finalCnt[j]+=finalCnt[ids]\n",
    "            elif num == 2:\n",
    "                for j in arr:\n",
    "                    fn[j]-=fn[ids]\n",
    "                    finalCnt[j]-=finalCnt[ids]\n",
    "            else:\n",
    "                fn[ids]*=2\n",
    "                finalCnt[ids]*=2\n",
    "        fnsum = sum(fn)\n",
    "        finalCntsum = sum(finalCnt)\n",
    "        for i in range(len(finalCnt)):\n",
    "            finalCnt[i] += fn[i]*((totalNum-finalCntsum)//fnsum)\n",
    "        return finalCnt\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        dc, finalCnt = defaultdict(list), [1j] + finalCnt\n",
    "        for i,j in edges:\n",
    "            dc[i].append(j)\n",
    "            dc[j].append(i)\n",
    "        for i,j in plans[::-1]:\n",
    "            v = finalCnt[j]\n",
    "            if i==1: finalCnt[j] *= 2\n",
    "            elif i==2:\n",
    "                for k in dc[j]: finalCnt[k] -= v\n",
    "            else:\n",
    "                for k in dc[j]: finalCnt[k] += v\n",
    "        sm = sum(finalCnt)\n",
    "        i = ((totalNum - sm.real) // sm.imag) if sm.imag else 0\n",
    "        return [int(x.real + x.imag * i) for x in finalCnt]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        changshu = [0] +finalCnt\n",
    "        xishu = [0] * (len(finalCnt)+1)\n",
    "        xishu[0] = 1\n",
    "        tu = collections.defaultdict(list)\n",
    "        for i in edges:\n",
    "            tu[i[1]].append(i[0])\n",
    "            tu[i[0]].append(i[1])\n",
    "\n",
    "        while plans:\n",
    "            caozuo,idx = plans.pop()\n",
    "            if caozuo == 1:\n",
    "                changshu[idx]*= 2\n",
    "                xishu[idx]*= 2\n",
    "            elif caozuo == 2:\n",
    "                for i in tu[idx]:\n",
    "                    changshu[i]-= changshu[idx]\n",
    "                    xishu[i]-= xishu[idx]\n",
    "            else:\n",
    "                for i in tu[idx]:\n",
    "                    changshu[i]+= changshu[idx]\n",
    "                    xishu[i]+= xishu[idx]\n",
    "\n",
    "\n",
    "        A = sum(xishu)\n",
    "        B = sum(changshu)\n",
    "        x = (totalNum-B)/A \n",
    "        ans = [0] * (len(finalCnt)+1)\n",
    "        for i in range(len(ans)):\n",
    "            ans[i] = int(xishu[i]*x + changshu[i])\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        def f1(edge, number, idx):\n",
    "            number[idx][0] *= 2\n",
    "            number[idx][1] *= 2\n",
    "            # if idx == 0:\n",
    "            #     number[idx][0] *= 2\n",
    "            # else:\n",
    "            #     number[idx][1] *= 2\n",
    "        \n",
    "        def f2(edge, number, idx):\n",
    "            nodes = edge[idx]\n",
    "            for node in nodes:\n",
    "                number[node][0] -= number[idx][0]\n",
    "                number[node][1] -= number[idx][1]\n",
    "            # if idx == 0:\n",
    "            #     for node in nodes:\n",
    "            #         number[node][0] += number[idx][0]\n",
    "            #         number[node][1] += number[idx][1]\n",
    "            # else:\n",
    "       \n",
    "        def f3(edge, number, idx):\n",
    "            nodes = edge[idx]\n",
    "            for node in nodes:\n",
    "                number[node][0] += number[idx][0]\n",
    "                number[node][1] += number[idx][1]\n",
    "        \n",
    "        edge = defaultdict(list)\n",
    "        for e in edges:\n",
    "            edge[e[0]].append(e[1])\n",
    "            edge[e[1]].append(e[0])\n",
    "        number = defaultdict(list)\n",
    "        number[0] = [1, 0]\n",
    "        for idx, cnt in enumerate(finalCnt):\n",
    "            number[idx+1] = [0, cnt]\n",
    "        \n",
    "        for plan in plans[::-1]:\n",
    "            if plan[0] == 1:\n",
    "                f1(edge, number, plan[1])\n",
    "                continue\n",
    "            if plan[0] == 2:\n",
    "                f2(edge, number, plan[1])\n",
    "                continue\n",
    "            if plan[0] == 3:\n",
    "                f3(edge, number, plan[1])\n",
    "                continue\n",
    "            \n",
    "        # x = (totalNum - sum([num[1] for num in number])) // (sum([num[0] for num in number]))\n",
    "        x = (totalNum - sum([num[1] for num in number.values()])) // sum([num[0] for num in number.values()])\n",
    "        res = []\n",
    "        for num in number.values():\n",
    "            res.append(num[0] * x+ num[1])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "        if len(grid) == 1:\n",
    "            return sum(grid[0])\n",
    "        if len(grid[0]) == 1:\n",
    "            return sum([x[0] for x in grid])\n",
    "        \n",
    "        m = len(grid)\n",
    "        n = len(grid[0])\n",
    "        dp = [0] * n\n",
    "        dp[0] = grid[0][0]\n",
    "        for j in range(1, n):\n",
    "            dp[j] = dp[j-1] + grid[0][j]\n",
    "        \n",
    "        for i in range(1, m):\n",
    "            dp[0] = dp[0] + grid[i][0]\n",
    "            for j in range(1, n):\n",
    "                dp[j] = min(dp[j], dp[j-1]) + grid[i][j]\n",
    "        \n",
    "        return dp[n-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "        m,n =len(grid),len(grid[0])\n",
    "        save = [[-1]*n for i in range(m)]\n",
    "        def dfs(i,j):\n",
    "            if i==0 and j ==0:\n",
    "                return grid[i][j]\n",
    "            if save[i][j]>=0:\n",
    "                return save[i][j]\n",
    "            if i==0 and j>0:\n",
    "                pathsum = dfs(i,j-1) + grid[i][j]\n",
    "            if j==0 and i>0:\n",
    "                pathsum = dfs(i-1,j) + grid[i][j]\n",
    "            if i>0 and j>0:\n",
    "                pathsum = min(dfs(i,j-1),dfs(i-1,j))+grid[i][j]\n",
    "            save[i][j] = pathsum\n",
    "            return pathsum\n",
    "        return dfs(m-1,n-1)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "\n",
    "        m,n = len(grid),len(grid[0])\n",
    "        save = [[-1 for j in range(n)]for i in range(m)]\n",
    "        def dfs(i,j): \n",
    "            if i == 0 and j == 0:\n",
    "                return grid[i][j]\n",
    "            if save[i][j]>=0:\n",
    "                return save[i][j]\n",
    "            if i==0 and j>0:\n",
    "                pathsum = dfs(i,j-1)+grid[i][j]\n",
    "            if j==0 and i>0:\n",
    "                pathsum =dfs(i-1,j)+grid[i][j]\n",
    "            elif i>0 and j >0:\n",
    "                pathsum = min(dfs(i-1,j), dfs(i,j-1))+grid[i][j]\n",
    "            save[i][j] =  pathsum\n",
    "            return pathsum\n",
    "        return dfs(m-1,n-1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "        m,n =len(grid),len(grid[0])\n",
    "        save = [[-1]*n for i in range(m)]\n",
    "        def dfs(i,j):\n",
    "            if i==0 and j ==0:\n",
    "                return grid[i][j]\n",
    "            if save[i][j]>=0:\n",
    "                return save[i][j]\n",
    "            if i==0 and j>0:\n",
    "                pathsum = dfs(i,j-1) + grid[i][j]\n",
    "            if j==0 and i>0:\n",
    "                pathsum = dfs(i-1,j) + grid[i][j]\n",
    "            if i>0 and j>0:\n",
    "                pathsum = min(dfs(i,j-1),dfs(i-1,j))+grid[i][j]\n",
    "            save[i][j] = pathsum\n",
    "            return pathsum\n",
    "        return dfs(m-1,n-1)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "\n",
    "        m,n = len(grid),len(grid[0])\n",
    "        save = [[-1 for j in range(n)]for i in range(m)]\n",
    "        def dfs(i,j): \n",
    "            if i == 0 and j == 0:\n",
    "                return grid[i][j]\n",
    "            if save[i][j]>=0:\n",
    "                return save[i][j]\n",
    "            if i==0 and j>0:\n",
    "                pathsum = dfs(i,j-1)+grid[i][j]\n",
    "            if j==0 and i>0:\n",
    "                pathsum =dfs(i-1,j)+grid[i][j]\n",
    "            elif i>0 and j >0:\n",
    "                pathsum = min(dfs(i-1,j), dfs(i,j-1))+grid[i][j]\n",
    "            save[i][j] =  pathsum\n",
    "            return pathsum\n",
    "        return dfs(m-1,n-1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "\n",
    "        m,n = len(grid),len(grid[0])\n",
    "        save = [[-1 for j in range(n)]for i in range(m)]\n",
    "        def dfs(i,j): \n",
    "            if i == 0 and j == 0:\n",
    "                return grid[i][j]\n",
    "            if save[i][j]>=0:\n",
    "                return save[i][j]\n",
    "            if i==0 and j>0:\n",
    "                pathsum = dfs(i,j-1)+grid[i][j]\n",
    "            if j==0 and i>0:\n",
    "                pathsum =dfs(i-1,j)+grid[i][j]\n",
    "            if i>0 and j >0:\n",
    "                pathsum = min(dfs(i-1,j), dfs(i,j-1))+grid[i][j]\n",
    "            save[i][j] =  pathsum\n",
    "            return pathsum\n",
    "        return dfs(m-1,n-1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "        m, n = len(grid), len(grid[0])\n",
    "\n",
    "        min_path = [[-1] * n for _ in range(m)]\n",
    "        min_path[0][0] = grid[0][0]\n",
    "\n",
    "        return self.sum_path(grid, min_path, m - 1, n - 1)\n",
    "\n",
    "    def sum_path(self, grid, min_path, m, n):\n",
    "        if m < 0 or n < 0:\n",
    "            return 9999\n",
    "        elif min_path[m][n] >= 0:\n",
    "            return min_path[m][n]\n",
    "        min_path[m][n] = (\n",
    "            min(self.sum_path(grid, min_path, m - 1, n), self.sum_path(grid, min_path, m, n - 1)) + grid[m][n]\n",
    "        )\n",
    "        return min_path[m][n]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid) -> int:\n",
    "        m = len(grid)\n",
    "        n = len(grid[0])\n",
    "        dp = [[0 for i in range(n)] for j in range(m)]\n",
    "        if n <= 1 or m <= 1:\n",
    "            return sum(grid[0])\n",
    "        dp[0][0] = grid[0][0]\n",
    "        for i in range(1,m):\n",
    "            dp[i][0] += dp[i-1][0] + grid[i][0]\n",
    "        for j in range(1,n):\n",
    "            dp[0][j] += dp[0][j-1]+ grid[0][j]\n",
    "        print(dp)\n",
    "        for i in range(1, m):\n",
    "            for j in range(1, n):\n",
    "                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]\n",
    "        print(dp)\n",
    "        return dp[-1][-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        n = len(source)\n",
    "        m = len(source[0])\n",
    "        sum = 0\n",
    "        li = []\n",
    "        for i in range(10001):\n",
    "            li.append(0)\n",
    "        for i in range(n):\n",
    "            for j in range(m):\n",
    "                li[source[i][j]] += 1\n",
    "                li[target[i][j]] -= 1\n",
    "        for i in li:\n",
    "            if i>0:\n",
    "                sum += i\n",
    "        return sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        a=sum(target,[])\n",
    "        for i in sum(source,[]):\n",
    "            if i in a:\n",
    "                a.remove(i)\n",
    "        return len(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        d = {}\n",
    "        for x in source:\n",
    "            for y in x:\n",
    "                if y in d:\n",
    "                    d[y] += 1\n",
    "                else:\n",
    "                    d[y] = 1\n",
    "        for x in target:\n",
    "            for y in x:\n",
    "                if y in d:\n",
    "                    d[y] -= 1\n",
    "                    if d[y] == 0:\n",
    "                        del d[y]\n",
    "                else:\n",
    "                    pass\n",
    "        #print(d)\n",
    "        return sum(d.values())\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        s={}\n",
    "        sum0=0\n",
    "        for i in source:\n",
    "            for j in i:\n",
    "                s[j]=s.get(j,0)+1\n",
    "        for i in target:\n",
    "            for j in i:\n",
    "                if j not in s:\n",
    "                    sum0+=1\n",
    "                else:\n",
    "                    s[j]-=1\n",
    "        for i in s:\n",
    "            if s[i]<0:\n",
    "                sum0+=abs(s[i])\n",
    "        return sum0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "\n",
    "        d = defaultdict(int)\n",
    "\n",
    "        for row in source:\n",
    "            for n in row:\n",
    "                d[n] += 1\n",
    "        \n",
    "        for row in target:\n",
    "            for n in row:\n",
    "                if d[n] > 0:\n",
    "                    d[n] -= 1\n",
    "        \n",
    "        return sum(d.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# from collections import defaultdict\n",
    "# class Solution:\n",
    "#     def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "#         dic=defaultdict(int)\n",
    "#         for row in source:\n",
    "#             for j in range(len(row)):\n",
    "#                 dic[row[j]]+=1\n",
    "        \n",
    "#         for row in target:\n",
    "#             for j in range(len(row)):\n",
    "#                 dic[row[j]]-=1\n",
    "#                 if dic[row[j]]==0:\n",
    "#                     del dic[row[j]]\n",
    "\n",
    "#         lst=[-v for k,v in dic.items() if v<0]\n",
    "\n",
    "#         return sum(lst) if lst else 0\n",
    "\n",
    "\n",
    "from collections import defaultdict\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        dic=defaultdict(int)\n",
    "        for row in source:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]+=1\n",
    "        cnt=0\n",
    "        for row in target:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]-=1\n",
    "                if dic[row[j]]>=0:\n",
    "                    cnt+=1\n",
    "                    # del dic[row[j]]\n",
    "\n",
    "        # lst=[-v for k,v in dic.items() if v<0]\n",
    "        return len(source)*len(source[0])-cnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        d = {}\n",
    "        for x in source:\n",
    "            for y in x:\n",
    "                if y in d:\n",
    "                    d[y] += 1\n",
    "                else:\n",
    "                    d[y] = 1\n",
    "\n",
    "        for x in target:\n",
    "            for y in x:\n",
    "                if y in d:\n",
    "                    d[y] -= 1\n",
    "                    if d[y] == 0:\n",
    "                        del d[y]\n",
    "                else:\n",
    "                    pass\n",
    "        #print(d)\n",
    "        return sum(d.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        for row in source:\n",
    "            for x in row:\n",
    "                cnt[x] += 1\n",
    "        for row in target:\n",
    "            for x in row:\n",
    "                cnt[x] -= 1\n",
    "        return sum(abs(x) for x in cnt.values()) // 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        n, m = len(source), len(source[0])\n",
    "        freq = {}\n",
    "        for i in range(n):\n",
    "            for j in range(m):\n",
    "                if source[i][j] not in freq:\n",
    "                    freq[source[i][j]] = 1\n",
    "                else:\n",
    "                    freq[source[i][j]] += 1\n",
    "        for i in range(n):\n",
    "            for j in range(m):\n",
    "                if target[i][j] in freq:\n",
    "                    if freq[target[i][j]] == 1:\n",
    "                        freq.pop(target[i][j])\n",
    "                    else:\n",
    "                        freq[target[i][j]] -= 1\n",
    "        return sum(freq.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        cnt = Counter()\n",
    "        m, n = len(source), len(source[0])\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                cnt[source[i][j]] += 1\n",
    "                cnt[target[i][j]] -= 1\n",
    "        return sum(abs(v) for v in cnt.values()) // 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        dic=defaultdict(int)\n",
    "        for row in source:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]+=1\n",
    "        \n",
    "        for row in target:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]-=1\n",
    "                if dic[row[j]]==0:\n",
    "                    del dic[row[j]]\n",
    "\n",
    "        lst=[-v for k,v in dic.items() if v<0]\n",
    "\n",
    "        return sum(lst) if lst else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "### my：哈希\n",
    "# from collections import defaultdict\n",
    "# class Solution:\n",
    "#     def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "#         dic=defaultdict(int)\n",
    "#         for row in source:\n",
    "#             for j in range(len(row)):\n",
    "#                 dic[row[j]]+=1\n",
    "        \n",
    "#         for row in target:\n",
    "#             for j in range(len(row)):\n",
    "#                 dic[row[j]]-=1\n",
    "#                 if dic[row[j]]==0:\n",
    "#                     del dic[row[j]]\n",
    "\n",
    "#         lst=[-v for k,v in dic.items() if v<0]\n",
    "\n",
    "#         return sum(lst) if lst else 0\n",
    "\n",
    "### my:哈希+计数（refer 网友）\n",
    "from collections import defaultdict\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        dic=defaultdict(int)\n",
    "        for row in source:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]+=1\n",
    "        cnt=0\n",
    "        for row in target:\n",
    "            for j in range(len(row)):\n",
    "                dic[row[j]]-=1\n",
    "                if dic[row[j]]>=0:\n",
    "                    cnt+=1\n",
    "                    # del dic[row[j]]\n",
    "\n",
    "        # lst=[-v for k,v in dic.items() if v<0]\n",
    "        return len(source)*len(source[0])-cnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        source = collections.Counter(itertools.chain(*source))\n",
    "        target = collections.Counter(itertools.chain(*target))\n",
    "        same = 0\n",
    "        for k, v in source.items():\n",
    "            same += min(v, target.get(k, 0))\n",
    "        return sum(source.values()) - same\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "#         import numpy as np\n",
    "#         # sourcecopy = source\n",
    "#         M = 0  #nums need change color\n",
    "#         A = len(target)\n",
    "#         B = len(target[-1])\n",
    "#         source_1 = list((np.array(source)).reshape(A*B,))\n",
    "#         target_1 = list((np.array(target)).reshape(A*B,))\n",
    "#         nums = len(target_1)\n",
    "#         # print('nums',target_1)\n",
    "#         for i in range(nums): #target 7\n",
    "#             M_tmp = 0\n",
    "#             for j in range(len(source_1)): \n",
    "#                 # print(i,j)\n",
    "#                 if target_1[i] == source_1[j]:\n",
    "#                     del source_1[j]\n",
    "#                     M_tmp = 1  # UAV不用变颜色\n",
    "#                     # print('source_1',source_1)\n",
    "#                     break              \n",
    "#             if M_tmp == 0:\n",
    "#                 M+=1\n",
    "#         print('M',M)\n",
    "#         return M\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import Counter\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        # a = [1,2,3,4]\n",
    "        # for i in range(0,2):\n",
    "        #     a.pop(a.index(a[i]))\n",
    "        # print(a)\n",
    "        ls1 = []\n",
    "        ls2 = []\n",
    "        for i in range(0,len(source)):\n",
    "            for j in range(0,len(source[0])):\n",
    "                ls1.append(source[i][j])\n",
    "        ls1.sort()\n",
    "        print(ls1)\n",
    "        for i in range(0,len(target)):\n",
    "            for j in range(0,len(target[0])):\n",
    "                ls2.append(target[i][j])\n",
    "        ls2.sort()\n",
    "        print(ls2)\n",
    "        print(len(ls1),len(ls2))\n",
    "        cnt =0\n",
    "        c1 = Counter(ls1)\n",
    "        \n",
    "        for x in ls2:\n",
    "            c1[x] -= 1\n",
    "        return sum([x for x in c1.values() if x >=0])\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from itertools import chain\n",
    "from collections import Counter\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source)) - Counter(chain(*target))).values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        cnt_s = Counter(sum(source,[]))\n",
    "        cnt_t = Counter(sum(target,[]))\n",
    "        return sum((cnt_t - cnt_s).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        from collections import Counter\n",
    "        sc = Counter(sum(source, []))\n",
    "        tc = Counter(sum(target, []))\n",
    "        res = 0\n",
    "        for i in sc.keys():\n",
    "            res += max(sc[i]-tc[i], 0)\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        s=[]\n",
    "        t=[]\n",
    "        for i in source:\n",
    "            s+=i\n",
    "        for i in target:\n",
    "            t+=i\n",
    "        s=collections.Counter(s)\n",
    "        t=collections.Counter(t)\n",
    "        a=(s-t).values()\n",
    "        return sum(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter(chain(*source))-Counter(chain(*target))).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        return sum((Counter([x for y in source for x in y])-Counter([x for y in target for x in y])).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import Counter\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source, [])),  Counter(sum(target, [])), 0\n",
    "        for i in set(c1): res += max(c1[i]-c2[i], 0)\n",
    "        return res\n",
    "    \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        from collections import Counter\n",
    "        sc = Counter(sum(source, []))\n",
    "        tc = Counter(sum(target, []))\n",
    "        res = 0\n",
    "        for i in set(sc): \n",
    "            res += max(sc[i]-tc[i], 0)\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        for i in set(c1): \n",
    "          res += max(c1[i]-c2[i],0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "#sum(二维列表,[])可以使列表降维\n",
    "        for i in set(c1): \n",
    "          res += max(c1[i]-c2[i],0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        for i in set(c1): res += max(c1[i]-c2[i],0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        from collections import Counter\n",
    "        sc = Counter(sum(source, []))\n",
    "        tc = Counter(sum(target, []))\n",
    "        res = 0\n",
    "        for i in set(sc):\n",
    "            res += max(sc[i]-tc[i], 0)\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        print(set(c1))\n",
    "#sum(二维列表,[])可以使列表降维\n",
    "        for i in set(c1): \n",
    "          res += max(c1[i]-c2[i],0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1 = collections.Counter(sum(target, []))\n",
    "        c2 = collections.Counter(sum(source, []))\n",
    "        return sum(abs(c1[i]-c2[i]) for i in c1.keys()|c2.keys())//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        for i in set(c2)|set(c1): res += abs(c2[i]-c1[i])\n",
    "        return res//2\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        for i in set(c2)|set(c1): res += abs(c2[i]-c1[i])\n",
    "        return res//2\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1,c2,res = Counter(sum(source,[])),Counter(sum(target,[])),0 #c1 c2是两个字典 统计两个列表中不同元素的个数 key是元素 value是个数\n",
    "        for i in set(c1)|set(c2):\n",
    "            res += abs(c1[i]-c2[i])\n",
    "        return res//2\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        ans = 0\n",
    "        cnt_s = Counter(sum(source,[]))\n",
    "        cnt_t = Counter(sum(target,[]))\n",
    "        for i in set(cnt_s)|set(cnt_t):\n",
    "            ans += abs(cnt_s[i] - cnt_t[i])\n",
    "        return ans//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1,c2,res = Counter(sum(source,[])),Counter(sum(target,[])),0 #c1 c2是两个字典 统计两个列表中不同元素的个数 key是元素 value是个数\n",
    "        for i in set(c1)|set(c2):\n",
    "            res += abs(c1[i]-c2[i])\n",
    "        return res//2\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "       c1=Counter(sum(source,[]))\n",
    "       c2=Counter(sum(target,[]))\n",
    "       res=0\n",
    "       for i in set(c2)|set(c1):\n",
    "          res=res+abs(c2[i]-c1[i])\n",
    "       return res//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "#         import numpy as np\n",
    "#         # sourcecopy = source\n",
    "#         M = 0  #nums need change color\n",
    "#         A = len(target)\n",
    "#         B = len(target[-1])\n",
    "#         source_1 = list((np.array(source)).reshape(A*B,))\n",
    "#         target_1 = list((np.array(target)).reshape(A*B,))\n",
    "#         nums = len(target_1)\n",
    "#         # print('nums',target_1)\n",
    "#         for i in range(nums): #target 7\n",
    "#             M_tmp = 0\n",
    "#             for j in range(len(source_1)): \n",
    "#                 # print(i,j)\n",
    "#                 if target_1[i] == source_1[j]:\n",
    "#                     del source_1[j]\n",
    "#                     M_tmp = 1  # UAV不用变颜色\n",
    "#                     # print('source_1',source_1)\n",
    "#                     break              \n",
    "#             if M_tmp == 0:\n",
    "#                 M+=1\n",
    "#         print('M',M)\n",
    "#         return M\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def minimumSwitchingTimes(self, source: List[List[int]], target: List[List[int]]) -> int:\n",
    "        c1, c2, res = Counter(sum(source,[])), Counter(sum(target,[])), 0\n",
    "        for i in set(c2)|set(c1): res += abs(c2[i]-c1[i])\n",
    "        return res//2\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        if len(s) == 0:\n",
    "            return []\n",
    "        path = []\n",
    "        reslist = []\n",
    "        def isvalid(ss):\n",
    "            l, r = 0, len(ss) - 1\n",
    "            if len(ss) > 1 and ss[0] == '0' or len(ss) == 0:\n",
    "                return False\n",
    "            if int(ss) <= 255 and int(ss) >= 0:\n",
    "                return True\n",
    "            return False\n",
    "            \n",
    "        p = 0\n",
    "        def backtracking(startindex, pointsum):\n",
    "            if pointsum >= 3:\n",
    "                if isvalid(s[startindex:len(s)]):\n",
    "                    ip = \".\".join(path[:]) + \".\" + s[startindex:len(s)]\n",
    "                    reslist.append(ip)\n",
    "                return\n",
    "\n",
    "            for i in range(startindex, len(s)):\n",
    "                if isvalid(s[startindex:i+1]): #注意字符串截取是左闭右开的\n",
    "                   path.append(s[startindex:i+1]) #此处添加的是子串s[startindex:i+1] ， 之前的组合问题添加的是单个字符/数字\n",
    "                   pointsum += 1\n",
    "                else:\n",
    "                    continue\n",
    "                backtracking(i + 1, pointsum)\n",
    "                path.pop()\n",
    "                pointsum -= 1\n",
    "            return\n",
    "        \n",
    "        backtracking(0, 0)\n",
    "        return reslist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def largestRectangleArea(self, heights: List[int]) -> int:\n",
    "        stack = []\n",
    "        maxn = 0\n",
    "        length = len(heights)\n",
    "        \n",
    "        heights.append(0)\n",
    "        heights.insert(0, 0)\n",
    "        #print(heights)\n",
    "        for idx in range(length+2):\n",
    "            while stack and (heights[idx] < heights[stack[-1]]):\n",
    "                sum = (idx - stack[-2] - 1)*heights[stack[-1]]\n",
    "                #print(idx, stack[-2], stack[-1], sum)\n",
    "                if sum > maxn:\n",
    "                    maxn = sum\n",
    "                print(maxn)\n",
    "                stack.pop()\n",
    "\n",
    "            stack.append(idx)\n",
    "            #print(heights[idx])\n",
    "\n",
    "        return maxn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        # 初始化已知营地集合\n",
    "        known_camps = set(expeditions[0].split('->')) if expeditions[0] else set()\n",
    "\n",
    "        max_new_camps = 0\n",
    "        best_index = -1\n",
    "\n",
    "        # 从第二个记录开始遍历\n",
    "        for idx, record in enumerate(expeditions[1:], 1):\n",
    "            camps = set(record.split('->')) if record else set()\n",
    "            new_camps_count = sum(1 for camp in camps if camp not in known_camps)\n",
    "\n",
    "            # 更新已知营地集合\n",
    "            known_camps.update(camps)\n",
    "\n",
    "            # 如果这次探险新发现的营地数量比目前最多的还要多\n",
    "            if new_camps_count > max_new_camps:\n",
    "                max_new_camps = new_camps_count\n",
    "                best_index = idx\n",
    "\n",
    "        return best_index if max_new_camps > 0 else -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        vis = []\n",
    "        for i in expeditions[0].split('->'):\n",
    "            if i == \"\":\n",
    "                continue\n",
    "            vis.append(i)\n",
    "        cao = []\n",
    "\n",
    "        for i,v in enumerate(expeditions):\n",
    "            if v==\"\":\n",
    "                cao.append(0)\n",
    "                continue\n",
    "            temp = v.split('->')\n",
    "            temp = list(set(temp))\n",
    "            cao.append(len(temp)-len(list(set(vis) & set(temp))))\n",
    "            vis.extend(list(set(temp)-(set(temp) & set(vis))))\n",
    "        if sum(cao) == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return cao.index(max(cao))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        vis = []\n",
    "        for i in expeditions[0].split('->'):\n",
    "            if i == \"\":\n",
    "                continue\n",
    "            vis.append(i)\n",
    "        cao = []\n",
    "\n",
    "        for i,v in enumerate(expeditions):\n",
    "            if v==\"\":\n",
    "                cao.append(0)\n",
    "                continue\n",
    "            temp = v.split('->')\n",
    "            temp = list(set(temp))\n",
    "            cao.append(len(temp)-len(list(set(vis) & set(temp))))\n",
    "            vis.extend(list(set(temp)-(set(temp) & set(vis))))\n",
    "        if sum(cao) == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return cao.index(max(cao))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        vis = []\n",
    "        for i in expeditions[0].split('->'):\n",
    "            if i == \"\":\n",
    "                continue\n",
    "            vis.append(i)\n",
    "        cao = []\n",
    "\n",
    "        for i,v in enumerate(expeditions):\n",
    "            if v==\"\":\n",
    "                cao.append(0)\n",
    "                continue\n",
    "            temp = v.split('->')\n",
    "            temp = list(set(temp))\n",
    "            cao.append(len(temp)-len(list(set(vis) & set(temp))))\n",
    "            vis.extend(list(set(temp)-(set(temp) & set(vis))))\n",
    "        if sum(cao) == 0:\n",
    "            return -1\n",
    "        else:\n",
    "            return cao.index(max(cao))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 数组：双指针\n",
    "        ret = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left, right = i + 1, len(nums) - 1\n",
    "            while left < right:\n",
    "                sums = nums[i] + nums[left] + nums[right]\n",
    "                if sums > 0:\n",
    "                    right -= 1\n",
    "                elif sums < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    ret.append([nums[i], nums[left], nums[right]])\n",
    "                    while left < right and nums[left] == nums[left + 1]:\n",
    "                        left += 1\n",
    "                    while left < right and nums[right] == nums[right - 1]:\n",
    "                        right -= 1\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        nums.sort()\n",
    "        for i in range(0, len(nums)):\n",
    "            if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "                continue\n",
    "            \n",
    "            # 左右指针从两边向中间对齐\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sum = nums[i] + nums[l] + nums[r]\n",
    "                left = nums[l]\n",
    "                right = nums[r]\n",
    "                if sum == 0:\n",
    "                    ans.append([nums[i], nums[l], nums[r]])\n",
    "                    # 去重第二、第三个数\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                    # l += 1\n",
    "                    # r -= 1\n",
    "                elif sum < 0:\n",
    "                    l += 1\n",
    "                elif sum > 0:\n",
    "                    r -= 1\n",
    "        return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针,可以通过。但是这个方法用在4Sum，无法通过\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         nums.sort()\n",
    "#         # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "#         # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "#         ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "#         return ans\n",
    "    \n",
    "#     def nSumTarget(self, nums, n, start, target):\n",
    "#         if len(nums) < n:\n",
    "#             return []\n",
    "#         if n < 2:# 至少是2Sum\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "        \n",
    "#         if n == 2: # 就是最好写的两数之和\n",
    "#         # 双指针那一套操作\n",
    "#             l, r = start, len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum_ = nums[l] + nums[r]\n",
    "#                 left, right = nums[l], nums[r]\n",
    "#                 if sum_ == target:\n",
    "#                     ans.append([left, right])\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                 elif sum_ > target:\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                 elif sum_ < target:\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#         else:\n",
    "#             # 大于2Sum的，先求n-1\n",
    "#             # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "#             for i in range(start, len(nums)):\n",
    "#                 if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "#                     continue\n",
    "\n",
    "#                 target_ = target - nums[i]\n",
    "#                 sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "#                 for arr in sub:\n",
    "#                     # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "#                     arr.append(nums[i])\n",
    "#                     ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "#         return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i in range(n):\n",
    "            if nums[i] > 0:\n",
    "                return ans  #返回ans而不是[]\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                sums = nums[i] + nums[left] + nums[right]\n",
    "                if sums > 0:\n",
    "                    right -= 1\n",
    "                elif sums < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    ans.append([nums[i], nums[left], nums[right]])\n",
    "                    while left < right and nums[left + 1] == nums[left]:\n",
    "                        left += 1\n",
    "                    while left < right and nums[right - 1] == nums[right]:\n",
    "                        right -= 1\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        #回溯时间太长，\n",
    "        # ans = []\n",
    "        # p = []\n",
    "        # nums.sort()\n",
    "        # used = [0]*len(nums)\n",
    "        # #回溯+这里的元素不可重复，因此设置一个索引\n",
    "        # def backtrac(num_arry,index,path,target):\n",
    "        #     if len(path) == 3 and target==0:\n",
    "        #         ans.append(path[:])\n",
    "        #         return\n",
    "            \n",
    "        #     if len(path)>3 or index>=len(num_arry):\n",
    "        #         return\n",
    "        #     if used[index]==1:\n",
    "        #         return \n",
    "        #     #我这里的情况是元素被重复使用了\n",
    "        #     for i in range(index,len(num_arry)):#这里如何约束\n",
    "        #         path.append(num_arry[i])\n",
    "        #         target -= num_arry[i]\n",
    "        #         used[i] = 1\n",
    "        #         backtrac(num_arry,i+1,path,target)\n",
    "        #         used[i] = 0\n",
    "        #         target += num_arry[i]\n",
    "        #         path.pop()\n",
    "\n",
    "        # #注意上面的for里面不返回，只有在符合条件时才返回\n",
    "        # backtrac(nums,0,p,0)\n",
    "        # #去重\n",
    "        # new_ans = []\n",
    "        # for value in ans:\n",
    "        #     if value not in new_ans:\n",
    "        #         new_ans.append(value)\n",
    "        # return new_ans\n",
    "\n",
    "        #所有查收元素和的问题都是双指针+排序\n",
    "        #和大于目标时，right--;和小于目标时，left ++\n",
    "        #三个数字时，迭代计算\n",
    "        #是否可以固定一个，然后left是他后面的位置\n",
    "        nums.sort()\n",
    "        #从0开始计算和为0的三元组\n",
    "        return self.nsumtarget(nums,3,0,0)#长度为3，开始位置为0，和为0\n",
    "\n",
    "    def nsumtarget(self,nums,n,index,target):\n",
    "        #判断一些可以直接排除的情况\n",
    "        sz = len(nums)\n",
    "        res = []\n",
    "        if n<2 or sz<n:\n",
    "            return res\n",
    "        #如果只只需查找两个\n",
    "        if n==2:\n",
    "            left = index\n",
    "            right = sz-1\n",
    "            while left<right:\n",
    "                sum_ = nums[left]+nums[right]\n",
    "                lv  = nums[left]\n",
    "                rv = nums[right]\n",
    "                #判断情况，觉得指针的移动情况\n",
    "                if sum_ == target:\n",
    "                    res.append([nums[left],nums[right]])\n",
    "                    #继续移动\n",
    "                    while left<right and nums[left]==lv:\n",
    "                        left += 1\n",
    "                    while left<right and nums[right] ==  rv:\n",
    "                        right -=1\n",
    "                elif sum_ < target:\n",
    "                    while left<right and nums[left] == lv:#跳过重复的元素\n",
    "                        left+=1\n",
    "                elif sum_>target:\n",
    "                    while left<right and nums[right]==rv:\n",
    "                        right -=1\n",
    "        else:\n",
    "            #元组长度大于2时，需要递归n-1的长度，然后添加上当前的值\n",
    "            for i in range(index,sz):#固定一个查找值\n",
    "                if i>0 and nums[i]==nums[i-1]:\n",
    "                    continue         \n",
    "                sub = self.nsumtarget(nums,n-1,i+1,target-nums[i])\n",
    "                for arr in sub:\n",
    "                    arr.append(nums[i])\n",
    "                    res.append(arr)\n",
    "\n",
    "        return res\n",
    "                \n",
    "\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        \n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "        # 双指针那一套操作\n",
    "            l, r = start, len(nums) - 1\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def twosum(nums,start,target):\n",
    "    res = []\n",
    "    left,right = start,len(nums)-1\n",
    "    while left < right:\n",
    "        left_num, right_num = nums[left], nums[right]\n",
    "        two_sum = left_num + right_num\n",
    "        if two_sum > target:\n",
    "            right -= 1\n",
    "            while left < right and nums[right] == right_num:\n",
    "                right -= 1\n",
    "        elif two_sum < target:\n",
    "            left += 1\n",
    "            while left < right and nums[left] == left_num:\n",
    "                left += 1\n",
    "        elif two_sum == target:\n",
    "            res.append([nums[left],nums[right]])\n",
    "            while left < right and nums[left] == left_num:\n",
    "                left += 1\n",
    "            while left < right and nums[right] == right_num:\n",
    "                right -= 1\n",
    "    return res\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        output = []\n",
    "        i = 0\n",
    "        while i < len(nums):\n",
    "            temp_res = twosum(nums,i+1,0-nums[i])\n",
    "\n",
    "            for item in temp_res:\n",
    "                item.append(nums[i])\n",
    "                output.append(item)\n",
    "            while i < len(nums) - 1 and nums[i] == nums[i + 1]:\n",
    "                i += 1\n",
    "            i += 1\n",
    "        return output\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        l, r = start, len(nums) - 1\n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr)\n",
    "        \n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        \n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "        # 双指针那一套操作\n",
    "            l, r = start, len(nums) - 1\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def dfs(self, used, nums, ind, current, ans, h):\n",
    "        if len(current) == 2:\n",
    "            lacked = -sum(current)\n",
    "            if lacked in h:\n",
    "                ind_left = h[lacked]\n",
    "                if ind_left >= ind:\n",
    "                    current += [nums[ind_left]]\n",
    "                    ans.append(current)\n",
    "            return\n",
    "\n",
    "        current_sum = sum(current)\n",
    "        for i, num in enumerate(nums[ind:]):\n",
    "            if used[i+ind] == 1:\n",
    "                continue\n",
    "            elif i+ind > 0 and nums[i+ind-1] == num and used[i+ind-1] == 0: \n",
    "                continue\n",
    "            elif sum(nums[i+ind:i+ind+(3-len(current))]) + current_sum > 0:\n",
    "                break\n",
    "            elif sum(nums[len(current)-3:]) + current_sum < 0:\n",
    "                break\n",
    "            else:\n",
    "                used[i+ind] = 1\n",
    "                self.dfs(used, nums, i+ind+1, current+[num], ans, h)\n",
    "                used[i+ind] = 0\n",
    "        return\n",
    "\n",
    "    def twoSum(self, nums, target, ans):\n",
    "        si = 0\n",
    "        ei = len(nums)\n",
    "        while si < ei-1:\n",
    "            if nums[si] + nums[ei-1] < target:\n",
    "                si += 1\n",
    "            elif nums[si] + nums[ei-1] > target:\n",
    "                ei -= 1\n",
    "            else:\n",
    "                ans.append([-target, nums[si], nums[ei-1]])\n",
    "                si += 1\n",
    "                while si < ei and nums[si-1] == nums[si] :\n",
    "                    si += 1\n",
    "        return \n",
    "\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i, num in enumerate(nums[:-2]):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            if -num <= 2 * nums[-1] and -num >= 2 * nums[i+1]:\n",
    "                self.twoSum(nums[i+1:], -num, ans)\n",
    "        return ans\n",
    "        # nums.sort()\n",
    "        # si = 0\n",
    "        # ei = len(nums)-1\n",
    "        # # h = {n:i for i,n in enumerate(nums)}\n",
    "        # num2ind = {}\n",
    "        # ans = []\n",
    "        # for i, n in enumerate(nums):\n",
    "        #     if n not in num2ind:\n",
    "        #         num2ind[n] = i\n",
    "        \n",
    "        # while si + 1 < ei:\n",
    "        #     lacked = 0 - nums[ei] - nums[si]\n",
    "        #     if lacked in num2ind:\n",
    "        #         ans.append([nums[si], nums[num2ind[lacked]], nums[ei]])\n",
    "                \n",
    "        #     else:\n",
    "        #         if nums[si] + nums[ei-1] + nums[ei] < 0:\n",
    "        #             while nums[si] == nums[si+1] and si < ei:\n",
    "        #                 si += 1\n",
    "        #         elif nums[si] + nums[si+1] + nums[ei] > 0:\n",
    "        #             while nums[ei] == nums[ei-1] and si < ei:\n",
    "        #                 ei -= 1\n",
    "        #         else:\n",
    "        #             si += 1\n",
    "        # return ans\n",
    "\n",
    "\n",
    "    def threeSum1(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        h = {n:i for i,n in enumerate(nums)}\n",
    "        ans = []\n",
    "        current = []\n",
    "\n",
    "        used = [0] * len(nums)\n",
    "        self.dfs(used, nums, 0, current, ans, h)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)       \n",
    "        nums.sort()\n",
    "        # res = []\n",
    "        ans = set()\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                sum = nums[i] + nums[left] + nums[right]\n",
    "                    # res.append([nums[i],nums[left],nums[right]])\n",
    "                if sum < 0:\n",
    "                    left += 1\n",
    "                elif sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    ans.add((nums[i],nums[left],nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1                    \n",
    "        return [list(a) for a in ans]\n",
    "                \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def dfs(self, used, nums, ind, current, ans, h):\n",
    "        if len(current) == 2:\n",
    "            # print(current)\n",
    "            lacked = -sum(current)\n",
    "            if lacked in h:\n",
    "                ind_left = h[lacked]\n",
    "                if ind_left >= ind:\n",
    "                    current += [nums[ind_left]]\n",
    "                    ans.append(current)\n",
    "            return\n",
    "\n",
    "        current_sum = sum(current)\n",
    "        for i, num in enumerate(nums[ind:]):\n",
    "            if used[i+ind] == 1:\n",
    "                continue\n",
    "            elif i+ind > 0 and nums[i+ind-1] == num and used[i+ind-1] == 0: \n",
    "                continue\n",
    "            elif sum(nums[i+ind:i+ind+(3-len(current))]) + current_sum > 0:\n",
    "                # print(\"to large\")\n",
    "                break\n",
    "            elif sum(nums[len(current)-3:]) + current_sum < 0:\n",
    "                # print(\"to small\")\n",
    "                break\n",
    "            else:\n",
    "                used[i+ind] = 1\n",
    "                self.dfs(used, nums, i+ind+1, current+[num], ans, h)\n",
    "                used[i+ind] = 0\n",
    "        return\n",
    "\n",
    "\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # sorted(nums)\n",
    "        nums.sort()\n",
    "        # print(nums)\n",
    "        h = {n:i for i,n in enumerate(nums)}\n",
    "        ans = []\n",
    "        current = []\n",
    "\n",
    "        used = [0] * len(nums)\n",
    "        self.dfs(used, nums, 0, current, ans, h)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        start = 0\n",
    "        res_set = set()\n",
    "        for start in range(n - 2):\n",
    "            left = start + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                cur_sum = nums[start] + nums[left] + nums[right]\n",
    "                if cur_sum == 0:\n",
    "                    res_set.add((nums[start], nums[left], nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif cur_sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "        res = [list(x) for x in res_set]\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        reapt = []\n",
    "        self.tup = []\n",
    "        for i,x in enumerate(nums):\n",
    "            if x not in reapt:\n",
    "                reapt.append(x)\n",
    "                self.tup = self.tup + self.twosum(i,-x,nums)\n",
    "        return self.tup\n",
    "\n",
    "\n",
    "    def twosum(self, index, target, nums):\n",
    "        m = {}\n",
    "        tup1 = []\n",
    "        nums = nums[index+1:]\n",
    "        for i,x in enumerate(nums):\n",
    "            # nums1 = nums.copy()\n",
    "            # nums1.pop(i)\n",
    "            #nums1 = nums[i+1:] \n",
    "            if target-x in m:\n",
    "                temp = [-target, x,target-x]\n",
    "                temp.sort()\n",
    "                if temp not in tup1 and temp not in self.tup:\n",
    "                    tup1.append(temp)\n",
    "            m[x] = i\n",
    "        return tup1\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         n = len(nums)\n",
    "#         nums.sort()\n",
    "#         ans = list()\n",
    "        \n",
    "#         # 枚举 a\n",
    "#         for first in range(n):\n",
    "#             # 需要和上一次枚举的数不相同\n",
    "#             if first > 0 and nums[first] == nums[first - 1]:\n",
    "#                 continue\n",
    "#             # c 对应的指针初始指向数组的最右端\n",
    "#             third = n - 1\n",
    "#             target = -nums[first]\n",
    "#             # 枚举 b\n",
    "#             for second in range(first + 1, n):\n",
    "#                 # 需要和上一次枚举的数不相同\n",
    "#                 if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "#                     continue\n",
    "#                 # 需要保证 b 的指针在 c 的指针的左侧\n",
    "#                 while second < third and nums[second] + nums[third] > target:\n",
    "#                     third -= 1\n",
    "#                 # 如果指针重合，随着 b 后续的增加\n",
    "#                 # 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环\n",
    "#                 if second == third:\n",
    "#                     break\n",
    "#                 if nums[second] + nums[third] == target:\n",
    "#                     ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "#         return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        reapt = []\n",
    "        self.tup = []\n",
    "        for i,x in enumerate(nums):\n",
    "            if x not in reapt:\n",
    "                reapt.append(x)\n",
    "                self.tup = self.tup + self.twosum(i,-x,nums)\n",
    "        return self.tup\n",
    "\n",
    "\n",
    "    def twosum(self, index, target, nums):\n",
    "        m = {}\n",
    "        tup1 = []\n",
    "        for i,x in enumerate(nums[index+1:]):\n",
    "            if target-x in m:\n",
    "                temp = [-target, x,target-x]\n",
    "                temp.sort()\n",
    "                if temp not in tup1 and temp not in self.tup:\n",
    "                    tup1.append(temp)\n",
    "            m[x] = i\n",
    "        return tup1\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         n = len(nums)\n",
    "#         nums.sort()\n",
    "#         ans = list()\n",
    "        \n",
    "#         # 枚举 a\n",
    "#         for first in range(n):\n",
    "#             # 需要和上一次枚举的数不相同\n",
    "#             if first > 0 and nums[first] == nums[first - 1]:\n",
    "#                 continue\n",
    "#             # c 对应的指针初始指向数组的最右端\n",
    "#             third = n - 1\n",
    "#             target = -nums[first]\n",
    "#             # 枚举 b\n",
    "#             for second in range(first + 1, n):\n",
    "#                 # 需要和上一次枚举的数不相同\n",
    "#                 if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "#                     continue\n",
    "#                 # 需要保证 b 的指针在 c 的指针的左侧\n",
    "#                 while second < third and nums[second] + nums[third] > target:\n",
    "#                     third -= 1\n",
    "#                 # 如果指针重合，随着 b 后续的增加\n",
    "#                 # 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环\n",
    "#                 if second == third:\n",
    "#                     break\n",
    "#                 if nums[second] + nums[third] == target:\n",
    "#                     ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "#         return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 如果是已经排序好的话，则时间复杂度位 O(n^2)\n",
    "        def twosum(nums, start, target):\n",
    "            left, right = start, len(nums) - 1\n",
    "            lr_list = []\n",
    "            while left < right:\n",
    "                sumval = nums[left] + nums[right]\n",
    "                if sumval == target:\n",
    "                    lr_list.append([left, right])\n",
    "                    right -= 1\n",
    "                elif sumval > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "            return lr_list\n",
    "        nums.sort()\n",
    "        flagSet = set()\n",
    "        result = []\n",
    "        N = len(nums)\n",
    "        for i in range(N-2):\n",
    "            target = 0 - nums[i]\n",
    "            lr_list = twosum(nums, i+1, target)\n",
    "            if len(lr_list) != 0:\n",
    "                for lr in lr_list:\n",
    "                    lstr = str([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                    if lstr not in flagSet:\n",
    "                        result.append([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                        flagSet.add(lstr)\n",
    "        return result\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countDigitOne(self, n: int) -> int:\n",
    "\n",
    "        high = n // 10\n",
    "        cur = n % 10\n",
    "        low = 0\n",
    "        digit = 1\n",
    "        sum_1 = 0\n",
    "        while high > 0 or cur > 0:\n",
    "\n",
    "            if cur < 1: sum_1 += high * digit\n",
    "            elif cur == 1: sum_1 += high * digit + low + 1\n",
    "            elif cur > 1: sum_1 += (high + 1) * digit\n",
    "\n",
    "            low += digit * cur\n",
    "            cur = high % 10\n",
    "            high //= 10\n",
    "            digit *= 10\n",
    "\n",
    "        return sum_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def digitOneInNumber(self, num: int) -> int:\n",
    "        dp = [[0 for i in range(10)] for j in range(11)]\n",
    "        dp[1][9] = 1\n",
    "        for i in range(2, len(dp)):\n",
    "            for j in range(len(dp[0])):\n",
    "                if j == 0:\n",
    "                    dp[i][j] = sum(dp[i-1])\n",
    "                elif j == 1:\n",
    "                    dp[i][j] = 10 ** (i-1) + dp[i][0]\n",
    "                else:\n",
    "                    dp[i][j] = dp[i][0]\n",
    "        res = 0\n",
    "        digit = len(str(num))\n",
    "        \n",
    "        while num >= 10:\n",
    "            tmp = 10 ** (digit-1)\n",
    "            index = 0\n",
    "            for i in range(0, 10):\n",
    "                index = i\n",
    "                if num - tmp < 0:\n",
    "                    break\n",
    "                else:\n",
    "                    res += dp[digit][i]\n",
    "                    num -= tmp\n",
    "            if index == 1:\n",
    "                res += num + 1\n",
    "            digit -= 1\n",
    "        if num >= 1:\n",
    "            return res + 1\n",
    "        else:\n",
    "            return res\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def getSchemeCount(self, n: int, m: int, chessboard: List[str]) -> int:\n",
    "        # n行m列\n",
    "        # 保证m小于n\n",
    "        if m > n:\n",
    "            # 行列交换\n",
    "            n, m = m, n\n",
    "            new = [[0] * m for _ in range(n)]\n",
    "\n",
    "            for i in range(n):\n",
    "                for j in range(m):\n",
    "                    new[i][j] = chessboard[j][i]\n",
    "\n",
    "            chessboard = new\n",
    "\n",
    "        # 动态规划，一行行计算，每一行最多3**m中可能（由于已知+魔法，还会少）\n",
    "        # key: 为前两行每列向上两个棋子\n",
    "        t = tuple([0] * (2 * m))\n",
    "        dp = {t: 1}\n",
    "\n",
    "        # 每行的所有可能性\n",
    "        dv = {\".\": 0, \"B\": 1, \"R\": 2}\n",
    "\n",
    "        def dfs(i, l=[], num1=0, num2=0):\n",
    "            if i == m:\n",
    "                yield l\n",
    "                return\n",
    "\n",
    "            v = dv.get(row[i])\n",
    "            if v == 0:\n",
    "                yield from dfs(i + 1, l + [0], num1, num2)\n",
    "                return\n",
    "\n",
    "            if v == 1:\n",
    "                if num1 != 2:\n",
    "                    yield from dfs(i + 1, l + [1], num2, 1)\n",
    "                return\n",
    "\n",
    "            if v == 2:\n",
    "                if num1 != 1:\n",
    "                    yield from dfs(i + 1, l + [2], num2, 2)\n",
    "                return\n",
    "\n",
    "            # ? 都有可能\n",
    "            yield from dfs(i + 1, l + [0], num1, num2)\n",
    "\n",
    "            if num1 != 2:\n",
    "                yield from dfs(i + 1, l + [1], num2, 1)\n",
    "\n",
    "            if num1 != 1:\n",
    "                yield from dfs(i + 1, l + [2], num2, 2)\n",
    "\n",
    "        for row in chessboard:\n",
    "            now = defaultdict(int)\n",
    "\n",
    "            for l in dfs(0):\n",
    "                for k, num in dp.items():\n",
    "                    # 判断列是否合法\n",
    "                    _k = list(k)\n",
    "\n",
    "                    for j, v in enumerate(l):\n",
    "                        if v == 0:\n",
    "                            continue\n",
    "\n",
    "                        j2 = j + j\n",
    "\n",
    "                        if v == 1:\n",
    "                            if k[j2] == 2:\n",
    "                                break\n",
    "                        elif k[j2] == 1:\n",
    "                            break\n",
    "\n",
    "                        _k[j2], _k[j2 + 1] = _k[j2 + 1], v\n",
    "                    else:\n",
    "                        now[tuple(_k)] += num\n",
    "\n",
    "            # print(now)\n",
    "            dp = now\n",
    "\n",
    "        return sum(dp.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSteps(self, n: int) -> int:\n",
    "        buf=[0, 0, 2, 3, 4, 5, 5, 7, 6, 6, 7, 11, 7, 13, 9, 8, 8, 17, 8, 19, 9, 10, 13, 23, 9, 10, 15, 9, 11, 29, 10, 31, 10, 14, 19, 12, 10, 37, 21, 16, 11, 41, 12, 43, 15, 11, 25, 47, 11, 14, 12, 20, 17, 53, 11, 16, 13, 22, 31, 59, 12, 61, 33, 13, 12, 18, 16, 67, 21, 26, 14, 71, 12, 73, 39, 13, 23, 18, 18, 79, 13, 12, 43, 83, 14, 22, 45, 32, 17, 89, 13, 20, 27, 34, 49, 24, 13, 97, 16, 17, 14, 101, 22, 103, 19, 15, 55, 107, 13, 109, 18, 40, 15, 113, 24, 28, 33, 19, 61, 24, 14, 22, 63, 44, 35, 15, 15, 127, 14, 46, 20, 131, 18, 26, 69, 14, 23, 137, 28, 139, 16, 50, 73, 24, 14, 34, 75, 17, 41, 149, 15, 151, 25, 23, 20, 36, 20, 157, 81, 56, 15, 30, 14, 163, 45, 19, 85, 167, 16, 26, 24, 25, 47, 173, 34, 17, 19, 62, 91, 179, 15, 181, 22, 64, 29, 42, 36, 28, 51, 16, 26, 191, 15, 193, 99, 21, 18, 197, 19, 199, 16, 70, 103, 36, 24, 46, 105, 29, 21, 30, 17, 211, 57, 74, 109, 48, 15, 38, 111, 76, 20, 30, 42, 223, 17, 16, 115, 227, 26, 229, 30, 21, 35, 233, 21, 52, 63, 82, 26, 239, 16, 241, 24, 15, 65, 19, 46, 32, 37, 86, 17, 251, 17, 34, 129, 25, 16, 257, 48, 44, 22, 35, 133, 263, 20, 58, 28, 92, 71, 269, 16, 271, 25, 23, 139, 21, 30, 277, 141, 37, 18, 281, 52, 283, 75, 27, 26, 48, 16, 34, 36, 100, 77, 293, 19, 64, 43, 20, 151, 36, 17, 50, 153, 104, 27, 66, 25, 307, 22, 106, 38, 311, 22, 313, 159, 18, 83, 317, 58, 40, 17, 110, 32, 36, 16, 23, 165, 112, 47, 54, 21, 331, 87, 43, 169, 72, 18, 337, 28, 116, 26, 42, 27, 21, 49, 31, 175, 347, 36, 349, 19, 22, 21, 353, 64, 76, 93, 27, 181, 359, 17, 38, 183, 25, 24, 78, 66, 367, 31, 47, 44, 60, 38, 373, 30, 18, 53, 42, 18, 379, 28, 130, 193, 383, 17, 23, 195, 49, 101, 389, 23, 40, 20, 134, 199, 84, 21, 397, 201, 29, 18, 401, 72, 44, 105, 17, 38, 48, 26, 409, 48, 140, 107, 66, 31, 88, 23, 142, 32, 419, 19, 421, 213, 53, 59, 27, 76, 68, 111, 27, 50, 431, 17, 433, 40, 37, 113, 42, 78, 439, 22, 20, 32, 443, 44, 94, 225, 152, 19, 449, 18, 52, 117, 154, 229, 25, 28, 457, 231, 26, 32, 461, 23, 463, 37, 39, 235, 467, 23, 74, 54, 160, 65, 54, 84, 29, 28, 59, 241, 479, 18, 50, 243, 33, 26, 102, 17, 487, 67, 166, 21, 491, 48, 46, 34, 22, 39, 78, 88, 499, 19, 170, 253, 503, 19, 106, 36, 29, 131, 509, 27, 80, 18, 28, 259, 108, 50, 58, 46, 176, 24, 521, 37, 523, 135, 20, 265, 48, 22, 46, 60, 65, 30, 54, 94, 112, 73, 182, 271, 25, 18, 541, 273, 184, 27, 114, 25, 547, 141, 67, 23, 48, 32, 86, 279, 45, 143, 557, 39, 56, 20, 31, 283, 563, 54, 118, 285, 19, 77, 569, 29, 571, 28, 194, 50, 33, 18, 577, 36, 196, 38, 90, 102, 64, 79, 24, 295, 587, 21, 50, 66, 200, 45, 593, 22, 29, 153, 202, 38, 599, 19, 601, 52, 73, 155, 27, 106, 607, 29, 39, 68, 60, 27, 613, 309, 49, 24, 617, 108, 619, 40, 32, 313, 96, 24, 20, 315, 33, 161, 54, 20, 631, 85, 214, 319, 132, 60, 27, 42, 77, 19, 641, 112, 643, 34, 51, 38, 647, 18, 70, 25, 41, 167, 653, 114, 136, 49, 79, 56, 659, 23, 661, 333, 33, 89, 31, 45, 52, 171, 226, 74, 72, 20, 673, 339, 19, 30, 677, 118, 104, 28, 230, 44, 683, 29, 142, 23, 232, 51, 66, 33, 691, 177, 24, 349, 144, 38, 58, 351, 236, 21, 701, 24, 56, 23, 55, 355, 108, 66, 709, 78, 85, 95, 54, 29, 29, 183, 242, 361, 719, 19, 110, 40, 244, 185, 39, 27, 727, 26, 18, 80, 60, 68, 733, 369, 22, 33, 78, 49, 739, 46, 35, 62, 743, 40, 154, 375, 89, 32, 114, 20, 751, 55, 254, 44, 156, 20, 757, 381, 37, 30, 761, 132, 116, 195, 28, 385, 72, 19, 769, 25, 260, 197, 773, 51, 41, 103, 47, 391, 60, 25, 82, 42, 38, 22, 162, 136, 787, 201, 266, 86, 120, 23, 74, 399, 61, 203, 797, 31, 64, 20, 95, 403, 84, 74, 35, 46, 272, 107, 809, 19, 811, 40, 274, 50, 168, 28, 62, 411, 26, 50, 821, 142, 823, 109, 24, 68, 827, 33, 829, 90, 280, 25, 31, 144, 172, 34, 40, 421, 839, 21, 58, 423, 284, 215, 31, 55, 29, 61, 286, 29, 60, 78, 853, 70, 30, 113, 857, 29, 859, 52, 51, 433, 863, 19, 178, 435, 37, 42, 90, 39, 80, 115, 103, 44, 22, 80, 877, 441, 296, 24, 881, 22, 883, 34, 67, 445, 887, 46, 134, 96, 23, 227, 66, 154, 184, 21, 39, 451, 60, 20, 70, 54, 53, 119, 186, 156, 907, 231, 107, 27, 911, 30, 94, 459, 69, 233, 138, 28, 919, 34, 310, 463, 84, 25, 47, 465, 109, 39, 929, 41, 33, 237, 314, 469, 33, 25, 937, 76, 316, 56, 941, 162, 64, 67, 21, 56, 947, 86, 86, 31, 320, 30, 953, 61, 196, 243, 43, 481, 144, 20, 62, 52, 113, 245, 198, 35, 967, 28, 39, 104, 971, 19, 146, 489, 26, 69, 977, 168, 100, 23, 115, 493, 983, 50, 202, 48, 57, 36, 66, 24, 991, 41, 334, 80, 204, 90, 997, 501, 46, 21]\n",
    "        return buf[n]\n",
    "    def t(self, n: int) -> int:\n",
    "        def get_el(num):\n",
    "            t=num\n",
    "            i=2\n",
    "            ans=[]\n",
    "            while t>=i:\n",
    "                if t%i==0:\n",
    "                    ans.append(i)\n",
    "                    t=t//i\n",
    "                else:\n",
    "                    i+=1\n",
    "            return ans\n",
    "        return sum([e for e in get_el(n)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSteps(self, n: int) -> int:\n",
    "        # cnt为操作次数，sum1为A的个数,len为当前可粘贴的长度\n",
    "        ans = 10000\n",
    "        def back(sum1, n, cnt, len1):\n",
    "            nonlocal ans\n",
    "            if sum1 == n:\n",
    "                ans = min(ans, cnt) \n",
    "                return\n",
    "            if sum1 > n:\n",
    "                return\n",
    "            # 每次加上一次的字符长度，或者当前的字符长度\n",
    "            back(sum1 + len1, n, cnt + 1, len1)\n",
    "            back(sum1 + sum1, n, cnt + 2, sum1)\n",
    "        \n",
    "        if n == 1:\n",
    "            return 0\n",
    "        back(1, n, 1, 1)\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def numDistinct(self, s: str, t: str) -> int:\n",
    "        if len(s)<len(t) :\n",
    "            return 0\n",
    "        if t==\"\" :\n",
    "            return 0\n",
    "        if len(t)==1 :\n",
    "            return s.count(t)\n",
    "        \n",
    "        # 经过上面的对特殊情况的处理, 已经保证 t 中至少包含2个字符，且 s 的长度不小于 t . \n",
    "        \n",
    "        vocab = \"abcdefghijklmnopqrstuvwxyz\"\n",
    "        vocab += vocab.upper()\n",
    "        s_index_list = dict( [ (i,[]) for i in vocab ] )\n",
    "        \n",
    "        for i,symbol in enumerate(s,start=0) :\n",
    "            s_index_list[symbol].append(i)\n",
    "            \n",
    "        t_index_list = dict( [ (i,[]) for i in range(len(t)) ] )\n",
    "        \n",
    "        for i,symbol in enumerate(t,start=0) :\n",
    "            temp = s_index_list[symbol]\n",
    "            if temp == [] :\n",
    "                return 0\n",
    "            else:\n",
    "                t_index_list[i].extend(temp)\n",
    "        \n",
    "        left_ptr = dict( [ (i,0) for i in range(len(t)) ] )\n",
    "        right_ptr = dict( [ (i,len(t_index_list[i])) for i in range(len(t)) ] )\n",
    "        \n",
    "        for i in range(1,len(t),1) :\n",
    "            for j,index in enumerate(t_index_list[i],start=0) :\n",
    "                if index > t_index_list[i-1][left_ptr[i-1]] :\n",
    "                    left_ptr[i] = j\n",
    "                    break\n",
    "                if j == len(t_index_list[i])-1 :\n",
    "                    return 0\n",
    "        \n",
    "        for i in range(len(t)-2,-1,-1) :\n",
    "            for j,index in enumerate(t_index_list[i][::-1],start=len(t_index_list[i])) :\n",
    "                if index < t_index_list[i+1][len(t_index_list[i+1])-1] :\n",
    "                    right_ptr[i] = j\n",
    "                    break\n",
    "        \n",
    "        count_list = dict( [ (i,[]) for i in range(len(t)) ] )\n",
    "        for i in range(len(t)-1,-1,-1) :\n",
    "            if i == len(t)-1 :\n",
    "                for _ in range(0,len(t_index_list[i][left_ptr[i]:right_ptr[i]]),1) :\n",
    "                    count_list[i].append(1)\n",
    "            else :\n",
    "                for index in t_index_list[i][left_ptr[i]:right_ptr[i]] :\n",
    "                    count = 0\n",
    "                    for j,index_ in enumerate(t_index_list[i+1][left_ptr[i+1]:right_ptr[i+1]],start=0) :\n",
    "                        if index_>index :\n",
    "                            count += count_list[i+1][j]\n",
    "                    count_list[i].append(count)\n",
    "        \n",
    "        return sum(count_list[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import numpy as np\n",
    "class Solution:\n",
    "    def numDistinct(self, s: str, t: str) -> int:\n",
    "        buffer = np.zeros(len(s), dtype = np.int32)\n",
    "        for i, char in enumerate(s):\n",
    "            if char == t[0]:\n",
    "                buffer[i] = 1\n",
    "        j = 1\n",
    "        while j < len(t) and np.any(buffer):\n",
    "            print(buffer)\n",
    "            for i in range(len(s) - 1, j - 1, -1):\n",
    "                if s[i] == t[j]:\n",
    "                    buffer[i] = np.sum(buffer[:i])\n",
    "                else:\n",
    "                    buffer[i] = 0\n",
    "            buffer[:j] = 0\n",
    "            \n",
    "            j += 1\n",
    "\n",
    "        # print(buffer)\n",
    "\n",
    "        # for i in range(len(s)):\n",
    "        #     for j in range(1, len(t)):\n",
    "        #         if s[i] == t[j]:\n",
    "        #             buffer[i, j] = sum(buffer[:i, j - 1])\n",
    "        \n",
    "        # print(buffer)\n",
    "        return int(sum(buffer))\n",
    "                 \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums) < target:\n",
    "            return 0\n",
    "        left = 0\n",
    "        re = math.pow(10, 5)\n",
    "        wim = 0\n",
    "\n",
    "        for right, x in enumerate(nums):\n",
    "            wim = wim + x\n",
    "            while wim>=target:\n",
    "                re = min(re,right-left+1)\n",
    "                wim =wim-nums[left]\n",
    "                left=left+1\n",
    "        return re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, s: int, nums: List[int]) -> int:        \n",
    "        if not nums:\n",
    "            return 0\n",
    "        \n",
    "        n = len(nums)\n",
    "        ans = n + 1\n",
    "        sums = [0]\n",
    "        for i in range(n):\n",
    "            sums.append(sums[-1] + nums[i])\n",
    "        \n",
    "        for i in range(1, n + 1):\n",
    "            target = s + sums[i - 1]\n",
    "            bound = bisect.bisect_left(sums, target)\n",
    "            if bound != len(sums):\n",
    "                ans = min(ans, bound - (i - 1))\n",
    "        \n",
    "        return 0 if ans == n + 1 else ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        start = end = sum0 = 0\n",
    "        min_len = inf\n",
    "        while end < len(nums):\n",
    "            sum0 += nums[end]\n",
    "            while start >= 0 and sum0 >= target:\n",
    "                min_len = min(min_len,end - start + 1)\n",
    "                sum0 -= nums[start]\n",
    "                start += 1 \n",
    "            end += 1\n",
    "        return min_len if min_len != inf else 0\n",
    "            \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        # 数组：快慢双指针\n",
    "        ret = float('inf')\n",
    "        slow, fast, sums = 0, 0, 0\n",
    "        while fast < len(nums):\n",
    "            sums += nums[fast]\n",
    "            while sums >= target:\n",
    "                ret = min(ret, fast - slow + 1)\n",
    "                sums -= nums[slow]\n",
    "                slow += 1\n",
    "            fast += 1\n",
    "        return ret if ret != float('inf') else 0\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        l, r = 0, 1\n",
    "        n = len(nums)\n",
    "        start = 0\n",
    "        end = n\n",
    "        while l <= r and r <= n:\n",
    "            su = sum(nums[l:r])\n",
    "            if su < target:\n",
    "                r += 1\n",
    "            elif su >= target:\n",
    "                if (end - start) > (r - l):\n",
    "                    start, end = l, r\n",
    "                l += 1\n",
    "        print(start,end)\n",
    "        if (end - start) == n and sum(nums) < target:\n",
    "            return 0\n",
    "        return end - start"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        \n",
    "\n",
    "        n = len(nums)\n",
    "        ans = n+1\n",
    "        sum =0\n",
    "        left = 0 \n",
    "        for right ,x in enumerate(nums):\n",
    "            sum += x\n",
    "            while sum - nums[left] >=target:\n",
    "                sum -=nums[left]\n",
    "                left+=1\n",
    "            if sum >= target:\n",
    "                ans = min(ans,right-left+1)\n",
    "        return ans if ans<=n else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "        re = math.pow(10, 5)\n",
    "        temp = []\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            temp.append(nums[i])\n",
    "            while sum(temp)>=target:\n",
    "                re = min(re, len(temp))\n",
    "                temp.pop(0)\n",
    "\n",
    "\n",
    "        return re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        \n",
    "        n = len(nums)\n",
    "        min_len = float('inf')\n",
    "\n",
    "        l, r = 0, 0\n",
    "\n",
    "        _sum = 0\n",
    "\n",
    "        while r < n:\n",
    "            _sum += nums[r]\n",
    "\n",
    "            while _sum >= target:\n",
    "                min_len = min(min_len, r - l + 1)\n",
    "                _sum -= nums[l]\n",
    "                l += 1\n",
    "            r +=1\n",
    "        return 0 if min_len == float('inf') else min_len"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "        if target in nums:\n",
    "            return 1\n",
    "        slow,fast=0,0\n",
    "        min_=float('inf')\n",
    "        result=0\n",
    "        while fast<len(nums):\n",
    "            result+=nums[fast]\n",
    "            while result>=target:\n",
    "                min_=min(min_,fast-slow+1)\n",
    "                result-=nums[slow]\n",
    "                slow+=1\n",
    "            fast+=1\n",
    "        return min_\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        start = end = sum0 = 0\n",
    "        min_len = float(\"inf\")\n",
    "        while end < len(nums):\n",
    "            sum0 += nums[end]\n",
    "            while start >= 0 and sum0 >= target:\n",
    "                min_len = min(min_len,end - start + 1)\n",
    "                sum0 -= nums[start]\n",
    "                start += 1 \n",
    "            end += 1\n",
    "        return min_len if min_len != inf else 0\n",
    "            \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return 0\n",
    "        start,end=0,0\n",
    "        sumval=0\n",
    "        ans=len(nums)+1\n",
    "        while end<len(nums):\n",
    "            sumval+=nums[end]\n",
    "            while sumval>=target:\n",
    "                ans=min(ans,end-start+1)\n",
    "                sumval-=nums[start]\n",
    "                start+=1\n",
    "            end+=1\n",
    "        if ans==len(nums)+1:\n",
    "            return 0\n",
    "        else:\n",
    "            return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        fast, slow, n = 0, 0, len(nums)\n",
    "        tmpsum, ret = 0, n + 1\n",
    "\n",
    "        while fast < n:\n",
    "            tmpsum += nums[fast]\n",
    "            while tmpsum >= target:\n",
    "                ret = min(ret, fast - slow + 1)\n",
    "                tmpsum -= nums[slow]\n",
    "                slow += 1\n",
    "            fast += 1\n",
    "            \n",
    "        return 0 if ret ==  n + 1 else ret\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        sum_tmp = nums[0]\n",
    "        rs = 10**6 if nums[0]<target else 1\n",
    "        nums_l = len(nums)\n",
    "\n",
    "        # 滑动窗口，先找到满足条件的，然后尽量缩小窗口；不断右移窗口\n",
    "        l, r = 0, 1  # 窗口左右边界\n",
    "        while r<nums_l:\n",
    "            sum_tmp += nums[r]\n",
    "\n",
    "            while sum_tmp>=target:  # 满足条件，缩窗口，找到到当前位置满足条件的最小长度\n",
    "                rs = min(rs, r-l+1)\n",
    "                sum_tmp -= nums[l]\n",
    "                l += 1\n",
    "            \n",
    "            r += 1\n",
    "\n",
    "\n",
    "        return rs if rs<10**6 else 0\n",
    "                    \n",
    "\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # 滑窗 时间复杂度O(n)\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        window_sum = 0\n",
    "        n = len(nums)\n",
    "        res = math.inf\n",
    "        l , r = 0, 0\n",
    "        for r in range(n):\n",
    "            window_sum += nums[r]\n",
    "            while window_sum >= target:\n",
    "                res = min(res, r - l + 1)\n",
    "                window_sum -= nums[l]\n",
    "                l += 1\n",
    "        return res if res <= len(nums) else 0\n",
    "\n",
    "    # 前缀和 + 二分 时间复杂度O(n log(n))\n",
    "    # def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "    #     n = len(nums)\n",
    "    #     res = math.inf\n",
    "    #     pre_sum = [0 for _ in range(n + 1)]\n",
    "    #     for i in range(0, n):\n",
    "    #         pre_sum[i + 1] = pre_sum[i] + nums[i]\n",
    "    #     if pre_sum[-1] < target: return 0\n",
    "    #     for i in range(n + 1):\n",
    "    #         l, r = i, n + 1\n",
    "    #         while l < r:\n",
    "    #             mid = l + (r - l) // 2\n",
    "    #             if pre_sum[mid] - pre_sum[i] >= target:\n",
    "    #                 r = mid\n",
    "    #             else:\n",
    "    #                 l = mid + 1\n",
    "    #         if l < n + 1:\n",
    "    #             res = min(res, l - i)\n",
    "    #     return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # 滑窗 时间复杂度O(n)\n",
    "    # def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "    #     window_sum = 0\n",
    "    #     n = len(nums)\n",
    "    #     res = math.inf\n",
    "    #     l , r = 0, 0\n",
    "    #     while r < n:\n",
    "    #         window_sum += nums[r]\n",
    "    #         while window_sum >= target:\n",
    "    #             res = min(res, r - l + 1)\n",
    "    #             window_sum -= nums[l]\n",
    "    #             l += 1\n",
    "    #         r += 1\n",
    "    #     return res if res <= len(nums) else 0\n",
    "\n",
    "    # 前缀和 + 二分 时间复杂度O(n log(n))\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = math.inf\n",
    "        for i in range(1, n):\n",
    "            nums[i] += nums[i - 1]\n",
    "        nums = [0] + nums\n",
    "        if nums[-1] < target: return 0\n",
    "        for i in range(n):\n",
    "            l, r = i, n\n",
    "            while l < r:\n",
    "                mid = l + (r - l) // 2\n",
    "                if nums[mid + 1] - nums[i] >= target:\n",
    "                    r = mid\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            if l < n:\n",
    "                res = min(res, l - i + 1)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        sum = 0\n",
    "        ans = inf\n",
    "        left = 0\n",
    "        for i in range(len(nums)):\n",
    "            sum += nums[i]\n",
    "            while sum >= target:\n",
    "                sum -= nums[left]\n",
    "                ans = min(ans, i - left + 1)\n",
    "                left += 1\n",
    "            print(i, sum, ans)\n",
    "        return ans if ans != inf else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if len(nums) <= 0:\n",
    "            return 0\n",
    "        left, right = 0, 0\n",
    "        temp = []\n",
    "        _min = float('inf')\n",
    "        _sum = 0\n",
    "        for right in range(len(nums)):\n",
    "            temp.append(nums[right])\n",
    "            _sum += nums[right]\n",
    "            while _sum >= target:\n",
    "                _min = min(_min, right - left + 1)\n",
    "                _sum -= nums[left]\n",
    "                left += 1\n",
    "                \n",
    "        if _min == float(inf):\n",
    "            _min = 0\n",
    "        return _min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums)<target: return 0\n",
    "        left = 0\n",
    "        sum_s = 0\n",
    "        res = 100000\n",
    "        for right in range(len(nums)):\n",
    "            sum_s += nums[right]\n",
    "            print(left,right,sum_s)\n",
    "            while sum_s>= target:\n",
    "                res = min(right-left+1, res)\n",
    "                sum_s -= nums[left]\n",
    "                left += 1\n",
    "        return res     \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        left=0\n",
    "        right=0\n",
    "        min_len=inf\n",
    "        nums_sum=0\n",
    "\n",
    "        while right < len(nums):\n",
    "            print(right,left,nums_sum,min_len)\n",
    "            nums_sum += nums[right]\n",
    "\n",
    "            while nums_sum >= target:\n",
    "                min_len=min(right-left+1,min_len)\n",
    "                nums_sum -= nums[left]\n",
    "                left += 1\n",
    "            right += 1\n",
    "        if min_len == inf :return 0\n",
    "        return min_len"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        ans = 1e7\n",
    "        left,right = 0,0\n",
    "        while left< len(nums) and right<len(nums):\n",
    "            cur = sum(nums[left:right+1])\n",
    "            print(cur)\n",
    "            if cur < target:\n",
    "                right+=1\n",
    "            else:\n",
    "                ans = min(ans, right-left+1)\n",
    "                left+=1\n",
    "        \n",
    "        return ans if ans < 1e6 else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        left = 0\n",
    "        right = 0\n",
    "        res = len(nums)+1\n",
    "        sum_tmp = nums[0]\n",
    "        while left < len(nums) and right < len(nums) and left <= right:\n",
    "            print(left)\n",
    "            print(right)\n",
    "            print(sum_tmp)\n",
    "            print(res)\n",
    "            if sum_tmp >= target:\n",
    "                res = min(res,right-left+1)\n",
    "                sum_tmp -= nums[left]\n",
    "                left += 1\n",
    "            if sum_tmp < target:\n",
    "                if right == len(nums)-1:\n",
    "                    res = min(res,len(nums)+1)\n",
    "                    break\n",
    "                else:\n",
    "                    right += 1\n",
    "                    sum_tmp += nums[right]\n",
    "        # print(res)       \n",
    "        if res == len(nums)+1:\n",
    "            res = 0\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        \"\"\"n = len(nums)\n",
    "        i, j = 0, 0\n",
    "        tmp = nums[0]\n",
    "        ans = 2**31-1\n",
    "        while True:\n",
    "            while j < n-1 and tmp < target:\n",
    "                j += 1\n",
    "                tmp += nums[j]\n",
    "            if j == n-1 and tmp < target:\n",
    "                break\n",
    "            ans = min(ans, j-i+1)\n",
    "            while i < j and tmp >= target:\n",
    "                tmp -= nums[i]\n",
    "                i += 1\n",
    "            if tmp < target:\n",
    "                ans = min(ans, j-i+2)\n",
    "            else:\n",
    "                ans = 1\n",
    "                break\n",
    "        return 0 if ans == 2**31-1 else ans\"\"\"\n",
    "        sums = [0]\n",
    "        n = len(nums)\n",
    "        ans = 2**31-1\n",
    "        for i in range(n):\n",
    "            sums.append(nums[i]+sums[-1])\n",
    "        for i in range(1, n+1):\n",
    "            if sums[i] < target:\n",
    "                continue\n",
    "            l, r = 0, i\n",
    "            while l <= r:\n",
    "                m = l + (r-l)//2\n",
    "                if sums[i]-sums[m]>= target and (m==i or sums[i]-sums[m+1]<target):\n",
    "                    l = m\n",
    "                    break\n",
    "                if sums[i]-sums[m]>=target:\n",
    "                    l = m+1\n",
    "                else:\n",
    "                    r = m-1\n",
    "            ans = min(ans, i-l)\n",
    "        return ans if ans <= n else 0\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums) < target :\n",
    "            return 0\n",
    "        left = 0\n",
    "        right = 0\n",
    "        result =0\n",
    "        count = float('inf')\n",
    "        while  right < len(nums)  :\n",
    "            if result < target :\n",
    "                result += nums[right]\n",
    "                right += 1\n",
    "            else :\n",
    "                count = min(count,right-left)\n",
    "                result -= nums[left]\n",
    "                left += 1\n",
    "            print(left,right,result,count)\n",
    "        while result >= target :\n",
    "            count = min(count,len(nums)-left)\n",
    "            result -= nums[left]\n",
    "            left += 1\n",
    "        return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        i = j = sum = temp = 0\n",
    "        print(nums, target)\n",
    "        while j<len(nums) or sum >= target:\n",
    "            if sum >= target:\n",
    "               sum -= nums[i]\n",
    "               i += 1\n",
    "            else:\n",
    "                sum += nums[j]\n",
    "                j+=1\n",
    "            if sum >= target and (temp > j - i  or temp == 0):\n",
    "                temp = j - i \n",
    "            print(sum,i,j,temp)\n",
    "        return temp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if target > sum(nums):\n",
    "            return 0\n",
    "        l1 = nums[:]\n",
    "        ans = 1\n",
    "        n = len(nums)\n",
    "        while ans <= n:\n",
    "            if target <= max(l1):\n",
    "                return ans\n",
    "            l1 = l1[:-1]\n",
    "            for i in range(ans, n):\n",
    "                l1[i - ans] += nums[i]\n",
    "            ans += 1\n",
    "        return 0\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "        cur=0\n",
    "        presum=[0]\n",
    "        for i in range(n):\n",
    "            cur+=nums[i]\n",
    "            presum.append(cur)\n",
    "        cmin=1\n",
    "        cmax=n\n",
    "        def check(mid):\n",
    "            e=[presum[i+mid]-presum[i] for i in range(n-mid+1)]\n",
    "            return max(e)>=target\n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            if check(mid):\n",
    "                cur=mid\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return cur"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        '''\n",
    "        l = 0                           # 初始化左边界\n",
    "        n = len(nums)\n",
    "        out = n+1                       # 初始化返回值 out = 最小值 or 最大值\n",
    "        res = 0\n",
    "        for r in range(n):              # for 右边界 in 可迭代对象:\n",
    "            res += nums[r]                  # 更新窗口内部信息\n",
    "            while res >= target:            # while 根据题意进行调整：\n",
    "                out = min(out, r-l+1)           # 比较并更新out(收缩场景时)\n",
    "                res -= nums[l]\n",
    "                l += 1                          # 扩张或收缩窗口大小\n",
    "                                            # 比较并更新out(扩张场景时)，本题为收缩场景\n",
    "        return 0 if out == n+1 else out\n",
    "        '''\n",
    "        n = len(nums)\n",
    "        part_sum = []\n",
    "        for i in range(n):\n",
    "            part_sum.append(sum(nums[:i+1]))\n",
    "        part_sum.insert(0,0)\n",
    "        print(part_sum)\n",
    "        \n",
    "        if part_sum[-1] < target:\n",
    "            return 0\n",
    "        \n",
    "        l = 0\n",
    "        out = n+1\n",
    "        for i in range(n+1):\n",
    "            new_target = part_sum[i] + target\n",
    "            l = i+1\n",
    "            r = n\n",
    "            while l < r:\n",
    "                mid = (l+r) // 2\n",
    "                if part_sum[mid] < new_target:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid\n",
    "            if part_sum[r] >= new_target:\n",
    "                out = min(out, r-i)\n",
    "            print(new_target,r,i,r-i)\n",
    "        return out\n",
    "            \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        #前缀和+二分\n",
    "        if not len(nums):\n",
    "            return 0\n",
    "        import bisect\n",
    "\n",
    "\n",
    "        sumn = [0, nums[0]]\n",
    "        for x in nums[1:]:\n",
    "            sumn.append(sumn[-1] + x)\n",
    "        if sumn[-1] < target:\n",
    "            return 0\n",
    "        else:\n",
    "            ans = len(nums)\n",
    "        for idx, x in enumerate(sumn):\n",
    "            r = bisect.bisect_left(sumn, x + target)\n",
    "            if r >=  len(sumn):\n",
    "                continue\n",
    "            if ans >= r - idx:\n",
    "                ans = r - idx\n",
    "        return ans\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "\n",
    "        ans = []\n",
    "        length = len(nums)\n",
    "        nums_sum = collections.deque()\n",
    "        if sum(nums)<target: return 0\n",
    "        for i in nums:\n",
    "            nums_sum.append(i)\n",
    "            if sum(nums_sum)>=target:\n",
    "                while nums_sum and sum(nums_sum)>=target:\n",
    "                    nums_sum.popleft()\n",
    "                ans.append(len(nums_sum)+1) \n",
    "        if len(ans)<1:return 0\n",
    "        return min(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            sum = 0\n",
    "            for j in range(i, n):\n",
    "                sum += nums[j]\n",
    "                if sum >= target:\n",
    "                    res.append(j-i+1)\n",
    "                    break\n",
    "        if res:\n",
    "            return min(res)\n",
    "        else:\n",
    "            return 0\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        res = []\n",
    "        sums = 0\n",
    "        slow = fast = 0\n",
    "        while fast < len(nums):\n",
    "            sums += nums[fast]\n",
    "            while sums >= target:\n",
    "                res.append(fast - slow + 1)\n",
    "                sums -= nums[slow]\n",
    "                slow += 1\n",
    "            fast += 1\n",
    "        \n",
    "        return min(res) if res else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        #特殊情况\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "\n",
    "        tmp = 0\n",
    "        n = len(nums)\n",
    "        min_length = 0\n",
    "        for i in range(n):\n",
    "            if nums[i]>=target:\n",
    "                return 1\n",
    "            tmp += nums[i]\n",
    "            nums[i] = tmp\n",
    "            if tmp >= target and min_length == 0:\n",
    "                min_length = i+1\n",
    "        #此时nums一定是一个递增数组。要找到nums[j]-nums[i]>=target成立时最小的j-i+1\n",
    "        for i in range(n-1):\n",
    "            for j in range(i+1,n):\n",
    "                if nums[j]-nums[i]>=target:\n",
    "                    min_length = min(min_length,j-i)\n",
    "                    break\n",
    "        print(nums,min_length)\n",
    "        return min_length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if target>sum(nums):\n",
    "            return 0\n",
    "        if target<=min(nums) or target in set(nums):\n",
    "            return 1\n",
    "        a,b=0,1\n",
    "        tsum=nums[a]\n",
    "        l=len(nums)\n",
    "        ans=10**5+1\n",
    "        while a<l and b<l and a<=b:\n",
    "            while b<l and tsum<target:\n",
    "                tsum+=nums[b]\n",
    "                b+=1\n",
    "            while a<l and a<=b and tsum>=target:\n",
    "                ans=min(ans, b-a)\n",
    "                tsum-=nums[a]\n",
    "                a+=1\n",
    "                \n",
    "\n",
    "            # if a+1<b:\n",
    "            #     tsum-=nums[a]\n",
    "            #     a+=1\n",
    "            # print(a,b,tsum)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        length  = len(nums)\n",
    "        res = []\n",
    "        i = 0\n",
    "        j = -1\n",
    "        sum = 0\n",
    "        while j<length-1:\n",
    "            if sum < target:\n",
    "                \n",
    "                j+=1\n",
    "                sum+=nums[j]               \n",
    "            else :\n",
    "                \n",
    "                res.append(j-i+1)\n",
    "                sum-=nums[i]\n",
    "                i+=1\n",
    "        while i<=j:\n",
    "            if sum<target:\n",
    "                break\n",
    "            else:    \n",
    "                res.append(j-i+1)\n",
    "                sum-=nums[i]\n",
    "                i+=1\n",
    "        if not res:return 0\n",
    "        return min(res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if sum(nums) < target: \n",
    "            return 0\n",
    "        dp = [9999 for _ in range(len(nums))]\n",
    "        c = 0\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i, len(nums)):\n",
    "                c += nums[j]\n",
    "                if c >= target:\n",
    "                    dp[i] = j-i+1\n",
    "                    break\n",
    "            c = 0\n",
    "        return min(dp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        res,i,j = [],0,1\n",
    "        while i < len(nums) and j <= len(nums):\n",
    "            j = i+1\n",
    "            while i < j and j <= len(nums):\n",
    "                if sum(nums[i:j])<target:j+=1\n",
    "                elif sum(nums[i:j])>=target:\n",
    "                    res.append(j-i)\n",
    "                    i+=1\n",
    "        return min(res) if len(res) else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        def list_sum(a,b):\n",
    "            summ=[]\n",
    "            for i in range(0,len(a)):\n",
    "                summ.append(a[i]+b[i])\n",
    "            return summ\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "        if max(nums)>=target:\n",
    "            return 1\n",
    "        slide_window=2\n",
    "        summ_list=[]\n",
    "        for i in range(0,len(nums)):\n",
    "            summ_list.append(nums[i])\n",
    "        while slide_window<=len(nums):\n",
    "            summ_list=list_sum(summ_list[0:len(nums)-slide_window+1],nums[slide_window-1:])\n",
    "            if max(summ_list)>=target:\n",
    "                return slide_window\n",
    "            # for i in range(0,len(nums)-slide_window+1):\n",
    "            #     for j in range(i,i+slide_window):\n",
    "            #         summ+=nums[j]\n",
    "            #     if summ>=target:\n",
    "            #         return slide_window\n",
    "            #     summ_list.append()\n",
    "            #     summ=0\n",
    "            slide_window+=1\n",
    "        return 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        res = []\n",
    "        \n",
    "        left = 0\n",
    "        right = 1\n",
    "        n = len(nums)\n",
    "        while right <= n:\n",
    "            if sum(nums[left:right]) == target:\n",
    "                res.append(right-left)\n",
    "                right += 1\n",
    "                left += 1\n",
    "\n",
    "            elif sum(nums[left:right]) < target:\n",
    "                right += 1\n",
    "            else:\n",
    "                res.append(right-left)  \n",
    "                left += 1\n",
    "        return min(res) if res else 0\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "    #     ''' 先进先出队列实现 '''\n",
    "    #     if sum(nums) < target: return 0\n",
    "    #     queue = []\n",
    "    #     min_len, cur_sum, cur_len = len(nums), 0, 0\n",
    "    #     for value in nums:\n",
    "    #         if value >= target: return 1\n",
    "    #         cur_sum += value\n",
    "    #         cur_len += 1\n",
    "    #         queue.append(value)\n",
    "    #         while cur_sum >= target:\n",
    "    #             if cur_len < min_len:\n",
    "    #                 min_len = cur_len\n",
    "    #             head = queue.pop(0)\n",
    "    #             cur_sum -= head\n",
    "    #             cur_len -= 1\n",
    "    #     return min_len\n",
    "\n",
    "        def minSubArrayLen(self, s: int, nums: List[int]) -> int:\n",
    "            if not nums or sum(nums) < s:\n",
    "                return 0\n",
    "        \n",
    "            n = len(nums)\n",
    "            ans = n + 1\n",
    "            sums = [0]\n",
    "            # 计算各位置的累积和\n",
    "            for i in range(n):\n",
    "                sums.append(sums[-1] + nums[i])\n",
    "            \n",
    "            for i in range(1, n+1):\n",
    "                # 寻找以当前位置i开头的连续子数组，且其和大于等于s\n",
    "                target = s + sums[i-1]\n",
    "                bound = bisect.bisect_left(sums, target)\n",
    "                if bound != len(sums):\n",
    "                    ans = min(ans, bound - (i - 1))\n",
    "            \n",
    "            return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        pre_sum = list(accumulate(nums, initial=0))\n",
    "        n = len(pre_sum)\n",
    "        res = inf\n",
    "        left = 0\n",
    "        for right in range(n):\n",
    "            while left <= right and pre_sum[right] - pre_sum[left] >= target:\n",
    "                    res = min(res,right-left)\n",
    "                    left +=1\n",
    "        return  0 if  res == inf else  res \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        s = sum(nums)\n",
    "        if target>s:\n",
    "            return 0\n",
    "        if target==s:\n",
    "            return len(nums)\n",
    "        ls,rs = [0 ],[0]\n",
    "        l,r = 0,0\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            l += nums[i]\n",
    "            r += nums[-i-1]\n",
    "            ls.append(l)\n",
    "            rs.append(r)\n",
    "        rs = rs[::-1]\n",
    "        l,r = 0,n\n",
    "        ml = n\n",
    "        target = s-target\n",
    "        while r>l and l>=0:\n",
    "            cur = ls[l]+rs[r]\n",
    "            if cur<=target:\n",
    "                ml = min(ml,r-l)\n",
    "                l+=1\n",
    "            else:\n",
    "                l-=1\n",
    "                r-=1\n",
    "        # l,r = 0,n\n",
    "        # while r>l:\n",
    "        #     cur = ls[l]+rs[r]\n",
    "        #     if cur<=target:\n",
    "        #         ml = min(ml,r-l)\n",
    "        #         if cur==target:\n",
    "        #             r-=1\n",
    "        #             l+=1\n",
    "        #         else:\n",
    "        #             r-=1\n",
    "        #     else:\n",
    "        #         r-=1\n",
    "        return  ml\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # 滑窗 时间复杂度O(n)\n",
    "    # def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "    #     window_sum = 0\n",
    "    #     n = len(nums)\n",
    "    #     res = math.inf\n",
    "    #     l , r = 0, 0\n",
    "    #     while r < n:\n",
    "    #         window_sum += nums[r]\n",
    "    #         while window_sum >= target:\n",
    "    #             res = min(res, r - l + 1)\n",
    "    #             window_sum -= nums[l]\n",
    "    #             l += 1\n",
    "    #         r += 1\n",
    "    #     return res if res <= len(nums) else 0\n",
    "\n",
    "    # 前缀和 + 二分 时间复杂度O(n log(n))\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        res = math.inf\n",
    "        pre_sum = [0 for _ in range(n + 1)]\n",
    "        for i in range(0, n):\n",
    "            pre_sum[i + 1] = pre_sum[i] + nums[i]\n",
    "        if pre_sum[-1] < target: return 0\n",
    "        for i in range(n + 1):\n",
    "            l, r = i, n + 1\n",
    "            while l < r:\n",
    "                mid = l + (r - l) // 2\n",
    "                if pre_sum[mid] - pre_sum[i] >= target:\n",
    "                    r = mid\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            if l < n + 1:\n",
    "                res = min(res, l - i)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        ans = float('inf')\n",
    "        sums = [0]\n",
    "        for i in range(len(nums)):\n",
    "            sums.append(sums[-1] + nums[i])\n",
    "        def binary_search(nums: List[int], target: int) -> int:\n",
    "            l = 0\n",
    "            r = len(nums)\n",
    "            while l < r:\n",
    "                mid = (l + r) // 2\n",
    "                if nums[mid] < target:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid\n",
    "            return l\n",
    "        for i in range(1, len(nums) + 1):\n",
    "            new_target = target + sums[i - 1]\n",
    "            idx = binary_search(sums, new_target)\n",
    "            if idx != len(sums):\n",
    "                ans = min(ans, idx - i + 1)\n",
    "        return 0 if ans == float('inf') else ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return 0\n",
    "        \n",
    "        n = len(nums)\n",
    "        ans = n + 1\n",
    "        sums = [0]\n",
    "        for i in range(n):\n",
    "            sums.append(sums[-1]+nums[i])\n",
    "        \n",
    "        for i in range(1,n+1):\n",
    "            s = target + sums[i-1]\n",
    "            bound = bisect.bisect_left(sums, s)\n",
    "            if bound != len(sums):\n",
    "                ans = min(ans, bound - (i - 1))\n",
    "            \n",
    "        return 0 if ans == n + 1 else ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, s: int, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return 0\n",
    "        \n",
    "        n = len(nums)\n",
    "        ans = n + 1\n",
    "        sums = [0]\n",
    "        for i in range(n):\n",
    "            sums.append(sums[-1] + nums[i])\n",
    "        \n",
    "        for i in range(1, n + 1):\n",
    "            target = s + sums[i - 1]\n",
    "            bound = bisect.bisect_left(sums, target)\n",
    "            if bound != len(sums):\n",
    "                ans = min(ans, bound - (i - 1))\n",
    "        \n",
    "        return 0 if ans == n + 1 else ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, s: int, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return 0\n",
    "        \n",
    "        n = len(nums)\n",
    "        ans = n + 1\n",
    "        sums = [0]\n",
    "        for i in range(n):\n",
    "            sums.append(sums[-1] + nums[i])\n",
    "        \n",
    "        for i in range(1, n + 1):\n",
    "            target = s + sums[i - 1]\n",
    "            bound = bisect.bisect_left(sums, target)\n",
    "            if bound != len(sums):\n",
    "                ans = min(ans, bound - (i - 1))\n",
    "        \n",
    "        return 0 if ans == n + 1 else ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, s: int, nums: List[int]) -> int:\n",
    "        if not nums:\n",
    "            return 0\n",
    "        \n",
    "        n = len(nums)\n",
    "        ans = n + 1\n",
    "        sums = [0]\n",
    "        for i in range(n):\n",
    "            sums.append(sums[-1] + nums[i])\n",
    "        \n",
    "        for i in range(1, n + 1):\n",
    "            target = s + sums[i - 1]\n",
    "            bound = bisect.bisect_left(sums, target)\n",
    "            if bound != len(sums):\n",
    "                ans = min(ans, bound - (i - 1))\n",
    "        \n",
    "        return 0 if ans == n + 1 else ans\n",
    "\n",
    "# 作者：力扣官方题解\n",
    "# 链接：https://leetcode.cn/problems/2VG8Kg/solutions/1037546/he-da-yu-deng-yu-target-de-zui-duan-zi-s-ixef/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def breakfastNumber(self, staple: List[int], drinks: List[int], x: int) -> int:\n",
    "\n",
    "        staple.sort(key = lambda x: x)\n",
    "        drinks.sort(key = lambda x: x)\n",
    "        i, j = 0, len(drinks)-1\n",
    "        n = len(staple)\n",
    "        ans = 0\n",
    "        while i < n and j > -1:\n",
    "            sum = staple[i] + drinks[j]\n",
    "            if sum <= x:\n",
    "                ans += j + 1\n",
    "                i += 1\n",
    "                ans %= 1000000007\n",
    "            else:\n",
    "                j -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def breakfastNumber(self, staple: List[int], drinks: List[int], x: int) -> int:\n",
    "        sum = 0\n",
    "        staple = sorted(staple)\n",
    "        drinks = sorted(drinks)\n",
    "        s = bisect.bisect_right(staple,x)\n",
    "        for i in staple[:s]:\n",
    "            j = bisect.bisect_right(drinks, x - i)\n",
    "            sum += j\n",
    "        return sum % 1000000007\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # https://codeforces.com/contest/1579/submission/130462038\n",
    "        # 二分答案\n",
    "        # 对于答案 mid, 存在一系列操作, 极差<=mid?\n",
    "        # 起点0, 低点min,高点max\n",
    "        # 现在进行平移: 低点0, 高点mid,起始点为 z [0,mid]\n",
    "        # 问题转化为: 是否存在起始点为 z , 且一系列操作都不超出[0,mid]的方案\n",
    "        # 设当前起始点集合为 [0,mid] 的所有数,共 mid+1个数\n",
    "        # 对于较大的数z,下一步可以 减去nums[i],来保证在区间\n",
    "        # 对于较小的数z,下一步可以 加上nums[i],来保证在区间\n",
    "        # 对于中间的数z,下一步可以 加减nums[i],可能都超出区间\n",
    "        # 如果存在z, 从起点到终点都有不超出[0,mid]的方案, 则答案有效\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        # 假设起点为0,下一步的范围即为[-maxnum,maxnum]\n",
    "        # 假设起点< 0,下一步的范围即为[起点,maxnum-abs(起点)]\n",
    "        # 假设起点> 0,下一步的范围即为[-maxnum+abs(起点),起点]\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # 使用状态压缩动态规划检查是否存在一个有效的操作序列\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        \n",
    "        # 二分查找确定最小的不适宜度\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    \n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        # 另一种状态压缩动态规划的实现\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # https://codeforces.com/contest/1579/submission/130462038\n",
    "        # 二分答案\n",
    "        # 对于答案 mid, 存在一系列操作, 极差<=mid?\n",
    "        # 起点0, 低点min,高点max\n",
    "        # 现在进行平移: 低点0, 高点mid,起始点为 z [0,mid]\n",
    "        # 问题转化为: 是否存在起始点为 z , 且一系列操作都不超出[0,mid]的方案\n",
    "        # 设当前起始点集合为 [0,mid] 的所有数,共 mid+1个数\n",
    "        # 对于较大的数z,下一步可以 减去nums[i],来保证在区间\n",
    "        # 对于较小的数z,下一步可以 加上nums[i],来保证在区间\n",
    "        # 对于中间的数z,下一步可以 加减nums[i],可能都超出区间\n",
    "        # 如果存在z, 从起点到终点都有不超出[0,mid]的方案, 则答案有效\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        # 假设起点为0,下一步的范围即为[-maxnum,maxnum]\n",
    "        # 假设起点< 0,下一步的范围即为[起点,maxnum-abs(起点)]\n",
    "        # 假设起点> 0,下一步的范围即为[-maxnum+abs(起点),起点]\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  \n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.path = \"\"\n",
    "        self.res = 0\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.traverse(root)\n",
    "        return self.res\n",
    "    def traverse(self,root):\n",
    "        if not root:\n",
    "            return\n",
    "        self.path +=str(root.val)\n",
    "        if not root.left and not root.right:\n",
    "            self.res+=int(self.path)\n",
    "        self.traverse(root.left)\n",
    "        self.traverse(root.right)\n",
    "        self.path = self.path[:-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    # 回溯法\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.sumn = 0\n",
    "        self.num = 0\n",
    "        self.dfs(root)\n",
    "        return self.sumn\n",
    "    \n",
    "    def dfs(self, node):\n",
    "        if not node:\n",
    "            return\n",
    "        self.num = self.num*10 + node.val\n",
    "        if not node.left and not node.right:\n",
    "            self.sumn += self.num\n",
    "        self.dfs(node.left)\n",
    "        self.dfs(node.right)\n",
    "        self.num = (self.num - node.val) // 10\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        al = []\n",
    "        tem = ''\n",
    "        def dfs(root, tem, al):\n",
    "            if root:\n",
    "                tem += str(root.val)\n",
    "            if not root.left and not root.right:\n",
    "                al.append(tem)\n",
    "            else:\n",
    "                if root.left:\n",
    "                    dfs(root.left, tem, al)\n",
    "                if root.right:\n",
    "                    dfs(root.right, tem, al)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        dfs(root, tem, al)\n",
    "        res = 0\n",
    "        for i in al:\n",
    "            res += int(i)\n",
    "        return res\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "from queue import Queue\n",
    "\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        sumn = 0\n",
    "        que = [root]\n",
    "        while que:\n",
    "            if not que[0].left and not que[0].right:\n",
    "                sumn += que[0].val\n",
    "            if que[0].left:\n",
    "                que.append(que[0].left)\n",
    "                que[0].left.val = 10*que[0].val + que[0].left.val\n",
    "            if que[0].right:\n",
    "                que.append(que[0].right)\n",
    "                que[0].right.val = 10*que[0].val + que[0].right.val\n",
    "            que.pop(0)\n",
    "        return sumn\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def DFS(self,root,number):\n",
    "        if root==None:\n",
    "            return number\n",
    "        \n",
    "        if root.left==None and root.right==None:\n",
    "            return number*10+root.val\n",
    "        \n",
    "        if root.left:\n",
    "            res1= self.DFS(root.left,number*10+root.val)\n",
    "        else:\n",
    "            res1 = 0\n",
    "            \n",
    "        if root.right:\n",
    "            res2 = self.DFS(root.right,number*10+root.val)\n",
    "        else:\n",
    "            res2 = 0\n",
    "            \n",
    "        return res1+res2\n",
    "    def sumNumbers(self, root: Optional[TreeNode]) -> int:\n",
    "        return self.DFS(root,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def helper(root, res):\n",
    "            if not root:\n",
    "                return 0\n",
    "            res = res*10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return res\n",
    "            return helper(root.left, res) + helper(root.right, res)\n",
    "        return helper(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.sum=0\n",
    "        self.num=0\n",
    "        def back(root):\n",
    "            if not root:\n",
    "                return\n",
    "            self.num = self.num * 10+root.val\n",
    "            if root.left==None and root.right==None:\n",
    "                self.sum+=self.num\n",
    "            back(root.left)\n",
    "            back(root.right)\n",
    "            self.num = (self.num-root.val)//10\n",
    "        back(root)\n",
    "        return self.sum\n",
    "        # self.sum=0\n",
    "        # def dfs(root, num):\n",
    "        #     if not root:\n",
    "        #         return\n",
    "        #     num = num * 10 + root.val\n",
    "        #     if not root.left and not root.right:\n",
    "        #         self.sum += num\n",
    "        #     dfs(root.left,num)\n",
    "        #     dfs(root.right,num)\n",
    "        # dfs(root,0)\n",
    "        # return self.sum\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            return self.findPath(root, 0)\n",
    "\n",
    "    def findPath(self, root, temp):\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            temp = temp*10 + root.val\n",
    "            if root.left is None and root.right is None:\n",
    "                return temp\n",
    "            else:\n",
    "                return self.findPath(root.left, temp) + self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def traverse(root, trace):\n",
    "            if not root:\n",
    "                return 0\n",
    "            new_trace = trace * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return new_trace            \n",
    "            return traverse(root.left, new_trace) + traverse(root.right, new_trace)\n",
    "        \n",
    "        return traverse(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, val):\n",
    "            if not node: return 0\n",
    "            val = val * 10 + node.val\n",
    "            if not (node.left or node.right):\n",
    "                return val\n",
    "            return dfs(node.left, val) + dfs(node.right, val)\n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        return self.search(root, 0)\n",
    "        \n",
    "    def search(self, node, nowSum):\n",
    "        if not node:\n",
    "            return 0\n",
    "        nowSum=nowSum*10+node.val\n",
    "        if not node.left and not node.right:\n",
    "            return nowSum\n",
    "        left=self.search(node.left, nowSum)\n",
    "        right=self.search(node.right, nowSum)\n",
    "        return left+right\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root: TreeNode, prevTotal: int) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            total = prevTotal * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(root.left, total) + dfs(root.right, total)\n",
    "\n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            return self.findPath(root, 0)\n",
    "\n",
    "    def findPath(self, root, temp):\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            temp = temp*10 + root.val\n",
    "            if root.left is None and root.right is None:\n",
    "                return temp\n",
    "            else:\n",
    "                return self.findPath(root.left, temp) + self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node: TreeNode, prevTotal: int)->int:\n",
    "            if not node: return 0\n",
    "            total = prevTotal * 10 + node.val\n",
    "            if not node.left and not node.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(node.left,total)+dfs(node.right,total)\n",
    "        \n",
    "        return dfs(root,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        ans = 0\n",
    "        def dfs(root, val) -> int:\n",
    "            val = val * 10 + root.val\n",
    "            if root.left == None and root.right == None:\n",
    "                nonlocal ans\n",
    "                ans += val\n",
    "            else:\n",
    "                if root.left: dfs(root.left, val)\n",
    "                if root.right: dfs(root.right, val)\n",
    "        dfs(root, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        return self.dfs(root, 0)\n",
    "    \n",
    "    def dfs(self, root, val):\n",
    "        if not root:\n",
    "            return 0\n",
    "        val = val * 10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            return val\n",
    "        return self.dfs(root.left, val) + self.dfs(root.right, val) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        res = 0\n",
    "        def recurse(node, load):\n",
    "            nonlocal res\n",
    "            if node == None:\n",
    "                tmp = 0\n",
    "                for v in load:\n",
    "                    tmp = tmp*10 +v\n",
    "                res +=tmp\n",
    "                return\n",
    "            v =node.val\n",
    "            if not node.left and not node.right:\n",
    "                t = load + [v]\n",
    "                tmp = 0\n",
    "                for v in t:\n",
    "                    tmp = tmp*10 +v\n",
    "                res +=tmp\n",
    "                return\n",
    "            if node.left:\n",
    "                recurse(node.left, load +[v])\n",
    "            if node.right:\n",
    "                recurse(node.right, load + [v])\n",
    "        recurse(root, [])\n",
    "        return res\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root,presum):\n",
    "            if root is None:\n",
    "                return 0\n",
    "            s = 10*presum+root.val\n",
    "            if root.left is None and root.right is None:\n",
    "                return s\n",
    "            return dfs(root.left,s)+dfs(root.right,s)\n",
    "        return dfs(root,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        ans=[]\n",
    "        def bl(p,t):\n",
    "            t=t+str(p.val)\n",
    "            if p.left:\n",
    "                bl(p.left,t)\n",
    "            if p.right:\n",
    "                bl(p.right,t)\n",
    "            if p.left is None and p.right is None:\n",
    "                ans.append(t)\n",
    "                return\n",
    "        if root is None: return 0\n",
    "        bl(root,'')\n",
    "        # print(ans)\n",
    "        res=0\n",
    "        for i in ans:\n",
    "            res+=int(i)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        # 每一次 dfs 形成一个数值\n",
    "        # 数值跟层次有关系,层次是递增的，没法形成有效的数计算，需要保存数值\n",
    "        # 再将数值累加\n",
    "        isLeafNode = lambda node: not node.left and not node.right\n",
    "\n",
    "        def dfs(node: TreeNode, prevTotal:int) -> int:\n",
    "\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            # 不加这个条件的话，就会导致两次计算\n",
    "            if isLeafNode(node):\n",
    "                return prevTotal * 10 + node.val\n",
    "            \n",
    "            left = dfs(node.left, prevTotal * 10 + node.val)\n",
    "            right = dfs(node.right, prevTotal * 10 + node.val)\n",
    "            return left + right \n",
    "\n",
    "        return dfs(root, 0) if root else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.ans = 0\n",
    "        def dfs(root, val):\n",
    "            if not root:\n",
    "                return\n",
    "            root.val += val * 10\n",
    "            dfs(root.left, root.val)\n",
    "            dfs(root.right, root.val)\n",
    "            if not root.left and not root.right:\n",
    "                self.ans += root.val\n",
    "        dfs(root, 0)\n",
    "        return self.ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "        ans = 0\n",
    "        def dfs(node: TreeNode, cur: int):\n",
    "            cur = cur * 10 + node.val\n",
    "            if node.left:\n",
    "                dfs(node.left, cur)\n",
    "            if node.right:\n",
    "                dfs(node.right, cur)\n",
    "            if not node.left and not node.right:\n",
    "                nonlocal ans\n",
    "                ans += cur\n",
    "        \n",
    "        dfs(root, 0)\n",
    "        return ans\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        res = 0\n",
    "        def dfs(node):\n",
    "            nonlocal res\n",
    "            if not node.left and not node.right:\n",
    "                res += node.val\n",
    "                return [1]\n",
    "            ret = []\n",
    "            if node.left:\n",
    "                lefts = dfs(node.left)\n",
    "                for left in lefts:\n",
    "                    res += pow(10,left)*node.val\n",
    "                    ret.append(left+1)\n",
    "            if node.right:\n",
    "                rights = dfs(node.right)\n",
    "                for right in rights:\n",
    "                    res += pow(10,right)*node.val\n",
    "                    ret.append(right+1)\n",
    "            return ret\n",
    "        rets = dfs(root)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def helper(root, cur_sum):\n",
    "            if not root:\n",
    "                return 0\n",
    "            cur_sum = cur_sum*10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return cur_sum\n",
    "            return helper(root.left, cur_sum) + helper(root.right, cur_sum)\n",
    "        return helper(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, val):\n",
    "            if not node: return 0\n",
    "            val = val * 10 + node.val\n",
    "            if not node.left and not node.right:\n",
    "                return val\n",
    "            return dfs(node.left, val) + dfs(node.right, val)\n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def preorder(root, preS):\n",
    "            if not root:\n",
    "                return 0\n",
    "            s  = preS * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return s\n",
    "            else: return preorder(root.left, s)  + preorder(root.right, s)\n",
    "        return preorder(root, 0)\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "    \n",
    "        res = 0\n",
    "        def dfs(root, num):\n",
    "            nonlocal res\n",
    "            if not root: return \n",
    "            if not root.left and not root.right:\n",
    "                res += num \n",
    "                return\n",
    "            if root.left:\n",
    "                dfs(root.left, num * 10 + root.left.val)\n",
    "            if root.right:\n",
    "                dfs(root.right, num * 10 + root.right.val)\n",
    "        dfs(root, root.val)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.num=0\n",
    "        def dfs(r:TreeNode,temp:int):\n",
    "            temp=temp*10+r.val\n",
    "            if not r.left and not r.right:\n",
    "                self.num+=temp\n",
    "                return\n",
    "            if r.left:dfs(r.left,temp)\n",
    "            if r.right:dfs(r.right,temp)\n",
    "        dfs(root,0)\n",
    "        return self.num\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.res, self.path_sum = 0, 0\n",
    "        def dfs(root):\n",
    "            self.path_sum = self.path_sum * 10 + root.val\n",
    "\n",
    "            if root.left:\n",
    "                dfs(root.left)\n",
    "            if root.right:\n",
    "                dfs(root.right)\n",
    "            elif not root.left:\n",
    "                self.res += self.path_sum\n",
    "            \n",
    "            self.path_sum = self.path_sum // 10\n",
    "            return\n",
    "        dfs(root)\n",
    "        return self.res\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, total):\n",
    "            if not node:\n",
    "                return 0\n",
    "            tmp = total * 10 + node.val\n",
    "            left = dfs(node.left, tmp)\n",
    "            right = dfs(node.right, tmp)\n",
    "            if not left and not right:\n",
    "                return tmp\n",
    "            return left + right\n",
    "\n",
    "        return dfs(root, 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        res = 0\n",
    "\n",
    "        if( not root):\n",
    "            return 0\n",
    "        self.sum1 = 0\n",
    "        def dfs(root, cur):\n",
    "            if(not root):\n",
    "                #self.sum1 = self.sum1 + (int)(cur)\n",
    "                return\n",
    "            if(not root.left and not root.right):\n",
    "                self.sum1 = self.sum1 + (int)(cur + str(root.val))\n",
    "                return \n",
    "            dfs(root.left, cur + str(root.val))\n",
    "            dfs(root.right,cur+str(root.val))\n",
    "\n",
    "        dfs(root, \"\")\n",
    "        return self.sum1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root, prevTotal) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            total = prevTotal * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(root.left, total) + dfs(root.right, total)\n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        res = 0\n",
    "        if root is None:\n",
    "            return res\n",
    "\n",
    "        def dfs(root, pathSum):\n",
    "            nonlocal res\n",
    "            # 只遍历非空节点\n",
    "            if root.left is None and root.right is None:\n",
    "                res += pathSum * 10 + root.val\n",
    "                return\n",
    "\n",
    "            pathSum = pathSum * 10 + root.val\n",
    "            if root.left is not None:\n",
    "                dfs(root.left, pathSum)\n",
    "            if root.right is not None:\n",
    "                dfs(root.right, pathSum)\n",
    "\n",
    "        dfs(root, 0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self) -> None:\n",
    "        self.stack = list()\n",
    "\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        return self.traverse(root)\n",
    "\n",
    "    def traverse(self, curr: TreeNode) -> int:\n",
    "        result = 0\n",
    "        if curr is None:\n",
    "            return 0\n",
    "        self.stack.append(curr.val)\n",
    "        if curr.left is None and curr.right is None:\n",
    "            ret = 0\n",
    "            for i in self.stack:\n",
    "                ret = ret * 10 + i\n",
    "            self.stack = self.stack[:-1]\n",
    "            return ret\n",
    "        if curr.left:\n",
    "            result += self.traverse(curr.left)\n",
    "        if curr.right:\n",
    "            result += self.traverse(curr.right)\n",
    "        self.stack = self.stack[:-1]\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def dfs(self, node, cur_val=0):\n",
    "        if not node:\n",
    "            return\n",
    "        cur_val =  10 * cur_val + node.val\n",
    "        if not node.left and not node.right:\n",
    "            self.sum += cur_val\n",
    "            return\n",
    "        self.dfs(node.left, cur_val)\n",
    "        self.dfs(node.right, cur_val)\n",
    "\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.sum = 0\n",
    "        self.dfs(root, 0)\n",
    "        return self.sum\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def func(root):\n",
    "            if not root:\n",
    "                return None\n",
    "            else:\n",
    "                res=[]\n",
    "                l=func(root.left)\n",
    "                r=func(root.right)\n",
    "                if l:\n",
    "                    for i in l:\n",
    "                        res.append('{}'.format(root.val)+i)\n",
    "                if r:\n",
    "                    for i in r:\n",
    "                        res.append('{}'.format(root.val)+i)\n",
    "                if not l and not r:\n",
    "                    res.append('{}'.format(root.val))\n",
    "                return res\n",
    "        res=func(root)\n",
    "        r=0\n",
    "        for i in res:\n",
    "            r+=int(i)\n",
    "        return r\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.sum_ = 0\n",
    "        self.back(root,0)\n",
    "        return self.sum_\n",
    "    def back(self,root,path):\n",
    "        if not root: \n",
    "            return path\n",
    "        path = path*10+root.val\n",
    "        if not root.left and not root.right: \n",
    "            self.sum_+=path\n",
    "            return (path-root.val)//10\n",
    "\n",
    "        path = self.back(root.left,path)\n",
    "        path = self.back(root.right,path)\n",
    "\n",
    "        return (path-root.val)//10\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.sum=0\n",
    "        def dfs(root, num):\n",
    "            if not root:\n",
    "                return\n",
    "            num = num * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                self.sum += num\n",
    "            dfs(root.left,num)\n",
    "            dfs(root.right,num)\n",
    "        dfs(root,0)\n",
    "        return self.sum\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "\n",
    "        def dfs(root,cur):\n",
    "            if not root:\n",
    "                return 0\n",
    "            if not root.left and not root.right:\n",
    "                return cur*10+root.val\n",
    "\n",
    "            return  dfs(root.left,cur*10+root.val)+dfs(root.right,cur*10+root.val)\n",
    "        \n",
    "        return dfs(root,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    res = 0\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "        def dfs(root,base):\n",
    "            if not root:\n",
    "                return\n",
    "            base  = base * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                self.res += base \n",
    "                base = 0 # 抵达叶子结点进行roll back\n",
    "            dfs(root.left,base)\n",
    "            dfs(root.right,base)\n",
    "        dfs(root,0)\n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "\n",
    "        if root is None:\n",
    "            return 0\n",
    "        node_list = [root]\n",
    "        result_list = [root.val]\n",
    "        count = 1\n",
    "        next_layer_count = 0\n",
    "        result = 0\n",
    "        while len(node_list)>0 and count > 0:\n",
    "            node = node_list.pop()\n",
    "            node_new_val = result_list.pop()\n",
    "            count -=1\n",
    "            if node.left is not None:\n",
    "                new_val = node_new_val*10 + node.left.val\n",
    "                next_layer_count +=1\n",
    "                result_list.append(new_val)\n",
    "                node_list.append(node.left)\n",
    "            if node.right is not None:\n",
    "                new_val = node_new_val*10 + node.right.val\n",
    "                next_layer_count +=1\n",
    "                result_list.append(new_val)\n",
    "                node_list.append(node.right)\n",
    "            # 叶子节点\n",
    "            if node.left is None and node.right is None:\n",
    "                result+=node_new_val\n",
    "            # 更新层信息\n",
    "            if next_layer_count>0 and count==0:\n",
    "                count = next_layer_count\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: Optional[TreeNode]) -> int:\n",
    "        return self.sum_numbers(root, 0)\n",
    "\n",
    "    def sum_numbers(self, root: Optional[TreeNode], num: int) -> int:\n",
    "        num = num * 10 + root.val\n",
    "        if root.left is None and root.right is None:\n",
    "            return num\n",
    "        left_num = 0\n",
    "        if root.left is not None:\n",
    "            left_num = self.sum_numbers(root.left, num)\n",
    "        right_num = 0\n",
    "        if root.right is not None:\n",
    "            right_num = self.sum_numbers(root.right, num)\n",
    "        return left_num + right_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "\n",
    "        res = []\n",
    "\n",
    "        def helper(node, path):\n",
    "            if not node:\n",
    "                return\n",
    "            path.append(node.val)\n",
    "            if not node.left and not node.right:\n",
    "                res.append(int(\"\".join(map(str, path))))\n",
    "            helper(node.left, path)\n",
    "            helper(node.right, path)\n",
    "            path.pop()\n",
    "\n",
    "        helper(root, [])\n",
    "        return sum(res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.dfs(root, 0)\n",
    "        return self.res\n",
    "    \n",
    "    def dfs(self, node, cnt):\n",
    "        if not node:\n",
    "            return 0\n",
    "        original = cnt\n",
    "        cnt = 10 * cnt + node.val\n",
    "        if not node.left and not node.right:\n",
    "            self.res += cnt\n",
    "            return\n",
    "        self.dfs(node.left, cnt)\n",
    "        self.dfs(node.right, cnt)\n",
    "        cnt = original"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root: TreeNode, prevTotal: int) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            total = prevTotal * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(root.left, total) + dfs(root.right, total)\n",
    "\n",
    "        return dfs(root, 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if not root: return 0\n",
    "        ans, p = [], [(root, str(root.val))]\n",
    "        while p:\n",
    "            tmp, s = p.pop(0)\n",
    "            if tmp.left: p.append((tmp.left, s+str(tmp.left.val)))\n",
    "            if tmp.right: p.append((tmp.right, s+str(tmp.right.val)))\n",
    "            if tmp.left==None and tmp.right==None: ans.append(s)\n",
    "        return sum(map(int, ans))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "        if not root.left and not root.right:\n",
    "            return root.val\n",
    "        if not root.left:\n",
    "            root.right.val += 10*root.val\n",
    "            return self.sumNumbers(root.right)\n",
    "        if not root.right:\n",
    "            root.left.val += 10*root.val\n",
    "            return self.sumNumbers(root.left)\n",
    "        root.left.val += 10*root.val\n",
    "        root.right.val += 10*root.val\n",
    "        return self.sumNumbers(root.left)+self.sumNumbers(root.right)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "    \n",
    "        self.res = 0\n",
    "        def dfs(root, num):\n",
    "            if not root:\n",
    "                return\n",
    "            if not root.left and not root.right:\n",
    "                self.res += num \n",
    "                return\n",
    "            if root.left:\n",
    "                dfs(root.left, num * 10 + root.left.val)\n",
    "            if root.right:\n",
    "                dfs(root.right, num * 10 + root.right.val)\n",
    "                \n",
    "        dfs(root, root.val)\n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        cnt = 0\n",
    "        def dfs(root, pre):\n",
    "            nonlocal cnt\n",
    "            if not root:\n",
    "                return\n",
    "            if not root.left and not root.right:\n",
    "                cnt += pre * 10 + root.val\n",
    "                return\n",
    "                \n",
    "            dfs(root.left, pre * 10 + root.val)\n",
    "            dfs(root.right, pre * 10 + root.val)\n",
    "        dfs(root, 0)\n",
    "        return cnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.res = 0\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            self.findPath(root, 0)\n",
    "            return self.res\n",
    "    def findPath(self, root, temp):\n",
    "        if not root:\n",
    "            return 0\n",
    "        temp = temp*10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            self.res += temp\n",
    "        else:\n",
    "            self.findPath(root.left, temp)\n",
    "            self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        global re\n",
    "        re = 0\n",
    "\n",
    "        def dfs(node, record):\n",
    "            global re\n",
    "            if node.left is None and node.right is None:\n",
    "                re += record*10+node.val\n",
    "            if node.left:\n",
    "                dfs(node.left, record*10+node.val)\n",
    "            if node.right:\n",
    "                dfs(node.right, record*10+node.val)\n",
    "\n",
    "        dfs(root, 0)\n",
    "\n",
    "        return re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root, p):\n",
    "            if not root: return 0\n",
    "            nonlocal ans\n",
    "            p = p*10+root.val\n",
    "            if not root.left and not root.right:\n",
    "                ans += p\n",
    "                return\n",
    "            dfs(root.left, p)\n",
    "            dfs(root.right, p)\n",
    "        \n",
    "        ans = 0\n",
    "        dfs(root, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root,c):\n",
    "            if not root:\n",
    "                return 0\n",
    "            if not root.left and not root.right:\n",
    "                c+=str(root.val)\n",
    "                return int(c)\n",
    "            c+=str(root.val)\n",
    "            return dfs(root.left,c)+dfs(root.right,c)\n",
    "        return dfs(root,'')\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root,sum,num):\n",
    "            if root is None:\n",
    "                return \n",
    "            num=10*num+root.val\n",
    "            if root.left is None and root.right is None:\n",
    "                sum[0]+=num\n",
    "            else:\n",
    "                dfs(root.left,sum,num)\n",
    "                dfs(root.right,sum,num)\n",
    "        \n",
    "        s=[0]\n",
    "        dfs(root,s,0)\n",
    "        return s[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "\n",
    "        def dfs(node, pre_total):\n",
    "            if not node:\n",
    "                return 0\n",
    "            \n",
    "            total = pre_total * 10 + node.val\n",
    "            if not node.left and not node.right:\n",
    "                return total\n",
    "            \n",
    "            else:\n",
    "                return dfs(node.left, total) + dfs(node.right, total)\n",
    "        \n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        method = 'mine'\n",
    "        if method == 'mine':\n",
    "            def dfs(root, s):\n",
    "                if root.left is None and root.right is None:\n",
    "                    s += str(root.val)\n",
    "                    res.append(s)\n",
    "                    return\n",
    "                elif root.left is None and root.right is not None:\n",
    "                    s += str(root.val)\n",
    "                    dfs(root.right, s)\n",
    "                elif root.left is not None and root.right is None:\n",
    "                    s += str(root.val)\n",
    "                    dfs(root.left, s)\n",
    "                else:\n",
    "                    s += str(root.val)\n",
    "                    dfs(root.left, s)\n",
    "                    dfs(root.right, s)\n",
    "            res = []\n",
    "            s = ''\n",
    "            dfs(root, s)\n",
    "            ans = 0\n",
    "            print(res)\n",
    "            for i in res:\n",
    "                ans += int(i)\n",
    "            return ans\n",
    "  \n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        return self._sum(root,0)\n",
    "    \n",
    "    def _sum(self,node,value):\n",
    "        if node==None:\n",
    "            return 0\n",
    "        value=value*10+node.val\n",
    "        if node.left==None and node.right==None:\n",
    "            return value\n",
    "        return self._sum(node.left,value)+self._sum(node.right,value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "# 注意：python 代码由 chatGPT\\U0001f916 根据我的 java 代码翻译，旨在帮助不同背景的读者理解算法逻辑。\n",
    "# 本代码已经通过力扣的测试用例，应该可直接成功提交。\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.path = \"\"\n",
    "        self.res = 0\n",
    "        \n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        # 遍历一遍二叉树就能出结果\n",
    "        self.traverse(root)\n",
    "        return self.res\n",
    "\n",
    "    # 二叉树遍历函数\n",
    "    def traverse(self, root: TreeNode) -> None:\n",
    "        if not root:\n",
    "            return\n",
    "        # 前序遍历位置，记录节点值\n",
    "        self.path += str(root.val)\n",
    "        if not root.left and not root.right:\n",
    "            # 到达叶子节点，累加路径和\n",
    "            self.res += int(self.path)\n",
    "        # 二叉树递归框架，遍历左右子树\n",
    "        self.traverse(root.left)\n",
    "        self.traverse(root.right)\n",
    "\n",
    "        # 后续遍历位置，撤销节点值\n",
    "        self.path = self.path[:-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.res = 0\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            self.findPath(root, 0)\n",
    "            return self.res\n",
    "    def findPath(self, root, temp):\n",
    "        if not root:\n",
    "            return 0\n",
    "        temp = temp*10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            self.res += temp\n",
    "        else:\n",
    "            self.findPath(root.left, temp)\n",
    "            self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        ans = 0\n",
    "        def dfs(root: Optional[TreeNode], currVal: int) -> None:\n",
    "            if not root:\n",
    "                return\n",
    "            nonlocal ans\n",
    "            if root.left is None and root.right is None:\n",
    "                ans += currVal * 10 + root.val\n",
    "                return\n",
    "            currVal = currVal * 10 + root.val\n",
    "            dfs(root.left, currVal)\n",
    "            dfs(root.right, currVal)\n",
    "        \n",
    "        dfs(root, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "\n",
    "        def recur(root, val):\n",
    "            if not root:\n",
    "                return 0\n",
    "            \n",
    "            val = val * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return val\n",
    "            \n",
    "            return recur(root.left, val) + recur(root.right, val)\n",
    "        \n",
    "        return recur(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root: TreeNode, prevTotal: int) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            total = prevTotal * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(root.left, total) + dfs(root.right, total)\n",
    "\n",
    "        return dfs(root, 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        \n",
    "        self.traverse(root, 0)\n",
    "        return self.res\n",
    "    \n",
    "    # 先序遍历的逻辑更顺\n",
    "    def traverse(self, node, path):\n",
    "        if not node:\n",
    "            return\n",
    "        if not node.left and not node.right:\n",
    "            path = 10 * path + node.val\n",
    "            self.res += path\n",
    "            return\n",
    "        path = 10 * path + node.val\n",
    "        self.traverse(node.left, path)\n",
    "        self.traverse(node.right, path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.res = 0\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            self.findPath(root, 0)\n",
    "            return self.res\n",
    "    def findPath(self, root, temp):\n",
    "        if not root:\n",
    "            return 0\n",
    "        temp = temp*10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            self.res += temp\n",
    "        else:\n",
    "            left = self.findPath(root.left, temp)\n",
    "            right = self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, tot):\n",
    "            if node is None:\n",
    "                return\n",
    "            tot = 10 * tot + node.val\n",
    "            if node.left is None and node.right is None:\n",
    "                nonlocal res\n",
    "                res += tot\n",
    "                return\n",
    "            dfs(node.left, tot)\n",
    "            dfs(node.right, tot)\n",
    "\n",
    "        res = 0\n",
    "        dfs(root, 0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    \n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, path_sum):\n",
    "            if not node.left and not node.right:\n",
    "                path_sum = path_sum * 10 + node.val\n",
    "                self.res += path_sum\n",
    "                return \n",
    "            if node.left:\n",
    "                dfs(node.left, path_sum*10 + node.val)\n",
    "            if node.right:\n",
    "                dfs(node.right, path_sum*10 + node.val)\n",
    "            \n",
    "        if not root:\n",
    "            return 0\n",
    "        self.res = 0\n",
    "        dfs(root, 0)\n",
    "    \n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(node, total):\n",
    "            if not node:\n",
    "                return 0\n",
    "            tmp = total + str(node.val)\n",
    "            left = dfs(node.left, tmp)\n",
    "            right = dfs(node.right, tmp)\n",
    "            if not left and not right:\n",
    "                return tmp\n",
    "            return int(left) + int(right)\n",
    "\n",
    "        return int(dfs(root, ''))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        return self.dfs(root, 0)\n",
    "\n",
    "    def dfs(self, root, path):\n",
    "        ### path 当前累计值\n",
    "        if not root:\n",
    "            return 0\n",
    "        path = path * 10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            return path\n",
    "\n",
    "        return self.dfs(root.left, path) + self.dfs(root.right, path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "\n",
    "        def dfs(root, i):\n",
    "            if not root:\n",
    "                return 0\n",
    "            v = root.val + 10 * i\n",
    "            if not root.left and not root.right:\n",
    "                return v\n",
    "            else:\n",
    "                return dfs(root.left, v) + dfs(root.right, v)\n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        def dfs(root: Optional[TreeNode], prev: int) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            total = prev * 10 + root.val\n",
    "            if not root.left and not root.right:\n",
    "                return total\n",
    "            else:\n",
    "                return dfs(root.left, total) + dfs(root.right, total)\n",
    "        \n",
    "        return dfs(root, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        self.res = 0\n",
    "        if root is None:\n",
    "            return 0\n",
    "        else:\n",
    "            self.findPath(root, 0)\n",
    "            return self.res\n",
    "    def findPath(self, root, temp):\n",
    "        if not root:\n",
    "            return 0\n",
    "        temp = temp*10 + root.val\n",
    "        if not root.left and not root.right:\n",
    "            self.res += temp\n",
    "        else:\n",
    "            left = self.findPath(root.left, temp)\n",
    "            right = self.findPath(root.right, temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def sumNumbers(self, root: TreeNode) -> int:\n",
    "        \n",
    "        self.ret = 0\n",
    "\n",
    "        def dfs(root, his):\n",
    "            if not root.left and not root.right:\n",
    "                print(root.val, his, root)\n",
    "                self.ret += int(his) \n",
    "                return   \n",
    "            if root.left:\n",
    "                dfs(root.left, his + str(root.left.val))\n",
    "            if root.right:\n",
    "                dfs(root.right, his + str(root.right.val))\n",
    "        \n",
    "        dfs(root, str(root.val))\n",
    "        return self.ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        dic={}\n",
    "        if len(nums)<3:\n",
    "            return sum(nums)\n",
    "        \n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sum = nums[i] + nums[l] + nums[r]\n",
    "                if sum < target:\n",
    "                    l += 1\n",
    "                    dic[sum] = target - sum\n",
    "                elif sum > target:\n",
    "                    r -= 1\n",
    "                    dic[sum] = sum - target\n",
    "                else:\n",
    "                    return target\n",
    "        return min(dic,key=dic.get)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        nums = sorted(nums)\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        i = 0\n",
    "        sum_num = nums[i] + nums[i + 1] + nums[i + 2]\n",
    "        closest = sum_num - target\n",
    "        while i < len(nums) - 2:\n",
    "            j = i + 1\n",
    "            k = len(nums) - 1\n",
    "\n",
    "            while j < k:\n",
    "                sum_num = nums[i] + nums[j] + nums[k]\n",
    "                close = sum_num - target\n",
    "\n",
    "                if close < 0:\n",
    "                    if abs(close) < abs(closest):\n",
    "                        closest = close\n",
    "                    j += 1\n",
    "                elif close > 0:\n",
    "                    if abs(close) < abs(closest):\n",
    "                        closest = close\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    return target\n",
    "            i += 1\n",
    "            while i < len(nums) and nums[i - 1] == nums[i]:\n",
    "                i += 1\n",
    "\n",
    "        return closest + target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)<3:\n",
    "            return 0\n",
    "        if len(nums) == 3:\n",
    "            return sum(nums)\n",
    "        \n",
    "        nums = sorted(nums)\n",
    "        tmp = nums[0] + nums[1] + nums[-1]\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue                \n",
    "            j = i + 1\n",
    "            k = len(nums)-1 \n",
    "            while j < k:\n",
    "                res = nums[i] + nums[j] + nums[k]\n",
    "                \n",
    "                if abs(res-target) < abs(tmp - target):\n",
    "                    tmp = res\n",
    "                elif res < target:\n",
    "                    j += 1\n",
    "                elif res == target:\n",
    "                     return res\n",
    "                else:\n",
    "                    k -= 1\n",
    "        return tmp\n",
    "                \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        \n",
    "        nums.sort()\n",
    "        init_num = float('inf')\n",
    "        result = []\n",
    "        for i in range(len(nums)):\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                tmp_sum = nums[i] + nums[left] + nums[right]\n",
    "                abs_num = abs(target - tmp_sum)\n",
    "                \n",
    "                if abs_num <= init_num:\n",
    "                    init_num = abs_num\n",
    "                    result.append(tmp_sum)\n",
    "                    \n",
    "                if tmp_sum < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "            \n",
    "        return result[-1]\n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        res=0\n",
    "        min_distance=9999\n",
    "        \n",
    "        nums.sort()\n",
    "        print(nums)\n",
    "        for i in range(len(nums)-2):\n",
    "            print('i:',i)\n",
    "            l=i+1\n",
    "            r=len(nums)-1\n",
    "            while(l<r):\n",
    "                sum = nums[i]+nums[l]+nums[r]\n",
    "                \n",
    "                if abs(target-sum)<min_distance:\n",
    "                    res=sum\n",
    "                    min_distance=abs(target-sum)\n",
    "                    print(i,l,r,sum)\n",
    "                    \n",
    "                if target==sum:\n",
    "                    return target\n",
    "                elif target>sum:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    r-=1\n",
    "                    \n",
    "\n",
    "        return res\n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: 'List[int]', target: 'int') -> 'int':\n",
    "        nums.sort()\n",
    "        len_nums = len(nums)\n",
    "        best_dist = float('inf')\n",
    "        best_sum = 0\n",
    "        res = []\n",
    "        for key, value in enumerate(nums[:len_nums-2]):\n",
    "            l, r = key+1,len_nums-1\n",
    "            if nums[l] + nums[l+1] + value > target:\n",
    "                res.append(nums[l] + nums[l+1] + value)\n",
    "            elif nums[r] + nums[r-1] + nums[r-2] < target:\n",
    "                res.append(nums[l] + nums[l+1] + value)\n",
    "            while l < r:\n",
    "                tmp = value + nums[l] + nums[r]\n",
    "                res.append(tmp)\n",
    "                if tmp == target:\n",
    "                    return target\n",
    "                \n",
    "                # if abs(tmp-target) < best_dist:\n",
    "                #     best_dist = abs(tmp-target)\n",
    "                #     best_sum = tmp\n",
    "                if tmp < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        # res.append(best_sum)\n",
    "        res.sort(key = lambda x: abs(x - target))\n",
    "        return res[0]\n",
    "                    \n",
    "            \n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        res = nums[0] + nums[1] + nums[2]\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                num_sum = nums[i] + nums[j] + nums[k]\n",
    "                if num_sum == target:\n",
    "                    return target\n",
    "                elif num_sum > target:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "                if abs(num_sum - target) < abs(res - target):\n",
    "                    res = num_sum\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        closest_sum = float('inf')\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            start = i+1\n",
    "            end = len(nums)-1\n",
    "            while(start < end):\n",
    "                temp = nums[i] + nums[start] + nums[end]\n",
    "                if(temp == target):\n",
    "                    return temp\n",
    "                elif(temp > target):\n",
    "                    end -= 1\n",
    "                else:\n",
    "                    start += 1\n",
    "                if(abs(closest_sum-target) > abs(temp-target)):\n",
    "                    closest_sum = temp\n",
    "        return closest_sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        ans = sum(nums[0:3])\n",
    "        if ans > target:\n",
    "            return ans\n",
    "        if sum(nums[-3:]) < target:\n",
    "            return sum(nums[-3:])\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while right > left:\n",
    "                _sum = nums[i] + nums[left] + nums[right]\n",
    "                if abs(_sum - target) < abs(ans-target):\n",
    "                    ans = _sum\n",
    "                if _sum > target:\n",
    "                    right -= 1\n",
    "                elif _sum < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    return _sum\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums or len(nums)<=2:\n",
    "            return\n",
    "        # if len(nums)==3:\n",
    "        #     return sum(nums)\n",
    "\n",
    "        nums.sort()\n",
    "        minsum = 1000000\n",
    "        res = 0\n",
    "        # res = []\n",
    "        for i in range(len(nums)-2):\n",
    "            m = i+1\n",
    "            n = len(nums)-1\n",
    "            while m<n:\n",
    "                tempsum = nums[i]+nums[m]+nums[n]\n",
    "                # print(nums[i],nums[m],nums[n])\n",
    "                # if tempsum==target:\n",
    "                #     return tempsum\n",
    "                if tempsum<target:\n",
    "                    m+=1\n",
    "                elif tempsum>target:\n",
    "                    n-=1\n",
    "                else:\n",
    "                    return tempsum\n",
    "                if abs(tempsum-target)<abs(minsum-target):\n",
    "                    minsum = tempsum\n",
    "\n",
    "        return minsum\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)<=3:\n",
    "            return sum(nums)\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<=target:\n",
    "            return sum(nums[-3:])\n",
    "        last_error=nums[0]+nums[1]+nums[2]-target\n",
    "        if last_error>=0:\n",
    "            return nums[0]+nums[1]+nums[2]\n",
    "        length=len(nums)\n",
    "        result=[last_error]\n",
    "        flag=False\n",
    "        for i in range(length-2):\n",
    "            for j in range(i+1,length-1):\n",
    "                for k in range(j+1,length):\n",
    "                    current=nums[i]+nums[j]+nums[k]\n",
    "                    error=current-target\n",
    "                    if error==0:\n",
    "                        return current\n",
    "                    elif error>0:\n",
    "                        if k>j+1:\n",
    "                            if abs(last_error)>error:\n",
    "                                result.append(error)\n",
    "                            else:\n",
    "                                result.append(last_error)\n",
    "                        else:\n",
    "                            result.append(error)\n",
    "                        break\n",
    "                    last_error=error\n",
    "                result.append(error) #if all is less than 0\n",
    "\n",
    "        min_error=result[0]\n",
    "        for index in range(1,len(result)):\n",
    "            error=result[index]\n",
    "            if abs(error)<abs(min_error):\n",
    "                min_error=error\n",
    "    \n",
    "        return target+min_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:       \n",
    "        nums=sorted(nums)\n",
    "        res=sum(nums[:3])\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i+1\n",
    "            right=len(nums)-1\n",
    "            while left<right:\n",
    "                if nums[i]+nums[left]+nums[right]-target==0:\n",
    "                    return nums[i]+nums[left]+nums[right]\n",
    "                if abs(nums[i]+nums[left]+nums[right]-target)<abs(res-target):\n",
    "                    res=(nums[i]+nums[left]+nums[right])\n",
    "                    continue\n",
    "                if nums[i]+nums[left]+nums[right]-target>0:\n",
    "                    right-=1\n",
    "                    continue\n",
    "                if nums[i]+nums[left]+nums[right]-target<0:\n",
    "                    left+=1\n",
    "        return res\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res = nums[0] + nums[1]+ nums[2]\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sums = nums[i]+ nums[l]+ nums[r]\n",
    "                if abs(target - sums) < abs(target - res):\n",
    "                    res = sums\n",
    "\n",
    "                if target > sums:\n",
    "                    l += 1\n",
    "                    \n",
    "                elif target < sums:\n",
    "                    r -= 1\n",
    "\n",
    "                else:\n",
    "                    return res\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        re_min = 0 #存储当前最小的差值\n",
    "        \n",
    "        for i in range(n):\n",
    "            low = i+1\n",
    "            high = n-1\n",
    "            while low < high:\n",
    "                three_sum = nums[i] + nums[low] + nums[high]\n",
    "                x = target - three_sum #当前三数的差值\n",
    "                if re_min == 0:\n",
    "                    re_min = abs(x)\n",
    "                    sum_min = three_sum #sum_min为当前最接近的和\n",
    "                \n",
    "                if abs(x) < re_min:\n",
    "                    re_min = abs(x)\n",
    "                    sum_min = three_sum\n",
    "                \n",
    "                if three_sum == target:\n",
    "                    return target\n",
    "                elif three_sum < target:\n",
    "                    low += 1\n",
    "                else:\n",
    "                    high -= 1\n",
    "        \n",
    "        return sum_min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums  or len(nums)<3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<target:\n",
    "            return len(nums)-2\n",
    "        if sum(nums[:3])>=target:\n",
    "            return 0\n",
    "        res = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            l = i+1\n",
    "            r = len(nums) -1 \n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < target:\n",
    "                    res = res + r - l\n",
    "                    l+=1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return res \n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return 0\n",
    "        res = 0\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            res += self.twoSumSmaller(nums, i+1, target-nums[i])\n",
    "        return res\n",
    "\n",
    "    def twoSumSmaller(self, nums, start, target):\n",
    "        num_small = 0\n",
    "        n = len(nums)\n",
    "        left,right = start,n-1\n",
    "        while left < right:\n",
    "            sum_ = nums[left] + nums[right]\n",
    "            if sum_ < target:\n",
    "                num_small += right-left\n",
    "                left += 1\n",
    "            else:\n",
    "                right -= 1\n",
    "        return num_small"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "\n",
    "\n",
    "\n",
    "        for i in range(n):\n",
    "            l,r = i+1,n-1\n",
    "            need = target - nums[i]\n",
    "            while l < r:\n",
    "                sumNum = nums[r] + nums[l]\n",
    "                if sumNum >= need:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    ans +=  r - l\n",
    "                    l += 1\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return 0\n",
    "        \n",
    "        count = 0\n",
    "        for i in range(n - 2):\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                temp_sum = nums[i] + nums[left] + nums[right]\n",
    "                if temp_sum < target:\n",
    "                    count += (right - left)\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums  or len(nums)<3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<target:\n",
    "            return len(nums)-2\n",
    "        if sum(nums[:3])>=target:\n",
    "            return 0\n",
    "        res = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            l = i+1\n",
    "            r = len(nums) -1 \n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < target:\n",
    "                    res = res + r - l\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return res \n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        def double_pointers(left, right):\n",
    "            count = 0\n",
    "            start = left - 1\n",
    "            while left < right:\n",
    "                cur_sum = nums[start] + nums[left] + nums[right]\n",
    "                if cur_sum < target:\n",
    "                    count += right - left\n",
    "                    left += 1  \n",
    "                else:\n",
    "                    right -= 1\n",
    "\n",
    "\n",
    "            # print(count)\n",
    "            return count\n",
    "        \n",
    "        n = len(nums)\n",
    "        # 特殊案例\n",
    "        if n == 0:\n",
    "            return 0\n",
    "        if n == 1:\n",
    "            if nums[0] < target:\n",
    "                return 1\n",
    "            else:\n",
    "                return 0\n",
    "        \n",
    "        nums.sort()\n",
    "        i = 0\n",
    "        count = 0\n",
    "        while i < n-2:\n",
    "            # print(i)\n",
    "            # if i > 0 and nums[i-1] == nums[i]:  # 由于返回的是下标的三元组，因此无需去重\n",
    "            #     i += 1\n",
    "            #     continue\n",
    "            count += double_pointers(i+1, n-1)\n",
    "            i += 1 \n",
    "        \n",
    "        return count \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        return sum(bisect.bisect_left(nums, target - nums[j] - nums[k], 0, j)\n",
    "            for k in range(len(nums)) for j in range(k)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) // 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)  # 频率\n",
    "        keys = sorted(count)  # key排序\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) // 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) // 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) // 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return ans % MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''\n",
    "三指针\n",
    "两数之和，双指针可行\n",
    "\n",
    "'''\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()  # 排序\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) // 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) / 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return int(ans)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        mp = {}\n",
    "        for x in arr:\n",
    "            mp[x] = mp.get(x, 0) + 1\n",
    "        # print(mp)\n",
    "        ans, n = 0, len(mp)\n",
    "        nums = [0] * n\n",
    "        i = 0\n",
    "        for x in mp:\n",
    "            nums[i] = x\n",
    "            i+=1\n",
    "        # print('nums : ',nums)\n",
    "\n",
    "        for i in range(n):\n",
    "            l, r = i, n-1\n",
    "            while l<=r:\n",
    "                tmpsum = nums[i] + nums[l] + nums[r]\n",
    "                # print('i:{}, l:{}, r:{}, ans:{}, sum:{}'.format(i, l, r, ans, tmpsum))\n",
    "                if tmpsum > target:\n",
    "                    r-=1\n",
    "                elif tmpsum < target:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    cnt1, cnt2 = 0, 0\n",
    "                    def calcnt(n1, n2)->int:\n",
    "                        cnt1 = mp[nums[n1]]\n",
    "                        cnt2 = mp[nums[n2]]\n",
    "                        # print('cal before [{}, {}]'.format(cnt1,cnt2))\n",
    "                        if cnt1 == 1:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 2:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 2)\n",
    "                        # print('calcnt({}, {}) -> {}'.format(n1, n2, cnt1*cnt2))\n",
    "                        return cnt1 * cnt2\n",
    "                    if (i == l and l != r):\n",
    "                        ans += calcnt(i, r)\n",
    "                    elif (i!=l and l==r):\n",
    "                        ans += calcnt(r, i)\n",
    "                    elif i!=l and l!=r:\n",
    "                        ans += mp[nums[i]] * mp[nums[l]] * mp[nums[r]]\n",
    "                    else: # 三者相等\n",
    "                        # print('i : {}, l : {}, r : {}'.format(i,l,r))\n",
    "                        cnt1 = mp[nums[i]]\n",
    "                        if cnt1 < 3:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 3:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 3)\n",
    "                        ans += cnt1\n",
    "                    l+=1\n",
    "\n",
    "\n",
    "        return ans % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "class Solution:\n",
    "    def find_targe_sum(self, arr, idx, target, selected_num, total):\n",
    "        if idx==len(arr) and total<3:\n",
    "            return\n",
    "        if total==3:\n",
    "            S = 0\n",
    "            result = 1\n",
    "            for num, freq, selected in selected_num:\n",
    "                S += num*selected\n",
    "                result *= math.comb(freq, selected)\n",
    "            if S==target:\n",
    "                self.result = (self.result+result)%(1e9+7)\n",
    "                # print(selected_num, result)\n",
    "            return\n",
    "        num, freq = arr[idx]\n",
    "        self.find_targe_sum(arr, idx+1, target, selected_num, total)\n",
    "        for i in range(1, min(4-total, freq+1)):\n",
    "            selected_num.append((num, freq, i))\n",
    "            self.find_targe_sum(arr, idx+1, target, selected_num, total+i)\n",
    "            selected_num.pop(-1)\n",
    "        return\n",
    "        \n",
    "\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr = sorted(arr)\n",
    "        arr_tuple = {}\n",
    "        for num in arr:\n",
    "            if num not in arr_tuple:\n",
    "                arr_tuple[num] = 1\n",
    "            else:\n",
    "                arr_tuple[num] += 1\n",
    "        arr_tuple = list(arr_tuple.items())\n",
    "        self.result = 0\n",
    "        self.find_targe_sum(arr_tuple, 0, target, [], 0)\n",
    "        return int(self.result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\r\n",
    "        ans = 0\r\n",
    "        arr = sorted(arr)\r\n",
    "        n = len(arr)\r\n",
    "        for first in range(n):\r\n",
    "            second,third = first+1,n-1\r\n",
    "            while second<third:\r\n",
    "                sums = arr[first]+arr[second]+arr[third]\r\n",
    "                if sums==target:\r\n",
    "                    # ans+=1\r\n",
    "                    # second+=1\r\n",
    "                    if arr[second]==arr[third]:\r\n",
    "                        ans+=(third-second+1)*(third-second)/2\r\n",
    "                        break\r\n",
    "                    t1,t2 = 1,1\r\n",
    "                    while arr[second]==arr[second+1] and second+1<=third:\r\n",
    "                        t1+=1\r\n",
    "                        second+=1\r\n",
    "                    while arr[third]==arr[third-1] and third-1>=second:\r\n",
    "                        t2+=1\r\n",
    "                        third-=1\r\n",
    "                    ans+=(t1*t2)\r\n",
    "                    second+=1\r\n",
    "                    third-=1\r\n",
    "                elif sums>target:\r\n",
    "                    third-=1\r\n",
    "                else:\r\n",
    "                    second+=1\r\n",
    "        return int(ans%(10**9+7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mp = Counter(arr)\n",
    "        keys = sorted(mp)\n",
    "        ans, n = 0, len(mp)\n",
    "\n",
    "        for i in range(n):\n",
    "            l, r = i, n-1\n",
    "            while l<=r:\n",
    "                tmpsum = keys[i] + keys[l] + keys[r]\n",
    "                # print('i:{}, l:{}, r:{}, ans:{}, sum:{}'.format(i, l, r, ans, tmpsum))\n",
    "                if tmpsum > target:\n",
    "                    r-=1\n",
    "                elif tmpsum < target:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    cnt1, cnt2 = 0, 0\n",
    "                    def calcnt(n1, n2)->int:\n",
    "                        cnt1 = mp[keys[n1]]\n",
    "                        cnt2 = mp[keys[n2]]\n",
    "                        # print('cal before [{}, {}]'.format(cnt1,cnt2))\n",
    "                        if cnt1 == 1:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 2:\n",
    "                            cnt1 = 1\n",
    "                        else: # 大于两个数，则进行组合，n选2\n",
    "                            cnt1 = comb(cnt1, 2) \n",
    "                        # print('calcnt({}, {}) -> {}'.format(n1, n2, cnt1*cnt2))\n",
    "                        return cnt1 * cnt2\n",
    "                    if (i == l and l != r): # 左边两个是同一个数\n",
    "                        ans += calcnt(i, r)\n",
    "                    elif (i!=l and l==r): # 右边两个是同一个数\n",
    "                        ans += calcnt(r, i)\n",
    "                    elif i!=l and l!=r: # 指向个不相同\n",
    "                        ans += mp[keys[i]] * mp[keys[l]] * mp[keys[r]]\n",
    "                    else: # 三个指针都指向同一个数\n",
    "                        # print('i : {}, l : {}, r : {}'.format(i,l,r))\n",
    "                        cnt1 = mp[keys[i]]\n",
    "                        if cnt1 < 3:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 3:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 3)\n",
    "                        ans += cnt1\n",
    "                    l+=1 # 哪个指针移动都可以，但是一定要移动\n",
    "\n",
    "\n",
    "        return ans % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mod = 10**9 + 7\n",
    "\n",
    "        count = Counter(arr)\n",
    "        keys = sorted(count) \n",
    "        len_distinct = len(keys)\n",
    "        res = 0\n",
    "\n",
    "        for left in range(len_distinct):\n",
    "            mid = left\n",
    "            right = len_distinct-1\n",
    "\n",
    "            while mid <= right:\n",
    "                cur_sum = keys[left] + keys[mid] + keys[right]\n",
    "                # print(left, mid, right)\n",
    "\n",
    "                if cur_sum == target:\n",
    "                    if left < mid < right:\n",
    "                        res += count[keys[left]] * count[keys[mid]] * count[keys[right]]\n",
    "                    elif left == mid < right:\n",
    "                        res += count[keys[left]] * (count[keys[mid]] - 1) / 2 * count[keys[right]]\n",
    "                    elif left < mid == right:\n",
    "                        res += count[keys[left]] * count[keys[mid]] * (count[keys[right]] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        res += count[keys[left]] * (count[keys[mid]] - 1) * (count[keys[right]] - 2) / 6\n",
    "                    # print(keys[left], keys[mid], keys[right])\n",
    "                    right -= 1\n",
    "                    mid += 1\n",
    "\n",
    "                if cur_sum > target:\n",
    "                    right -= 1\n",
    "\n",
    "                if cur_sum < target:\n",
    "                    mid += 1\n",
    "\n",
    "        return int(res % mod)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        print(count)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: 'List[int]') -> 'List[List[int]]':\n",
    "        def search_2sum(nums, target):\n",
    "            n = len(nums)\n",
    "            i, j = 0, n - 1\n",
    "            ret = []\n",
    "            while i < j:\n",
    "                if nums[i] + nums[j] == target:\n",
    "                    ret.append([nums[i], nums[j], -target])\n",
    "                    i, j = i + 1, j - 1\n",
    "                    while i < j and nums[i - 1] == nums[i]:\n",
    "                        i += 1\n",
    "                    while i < j and nums[j + 1] == nums[j]:\n",
    "                        j -= 1\n",
    "                elif nums[i] + nums[j] < target:\n",
    "                    l, r = i, j - 1\n",
    "                    while l <= r:\n",
    "                        c = (l + r) // 2\n",
    "                        if nums[c] + nums[j] == target:\n",
    "                            l = c\n",
    "                            break\n",
    "                        elif nums[c] + nums[j] < target:\n",
    "                            l = c + 1\n",
    "                        else:\n",
    "                            r = c - 1\n",
    "                    i = l\n",
    "                else:\n",
    "                    l, r = i + 1, j\n",
    "                    while l <= r:\n",
    "                        c = (l + r) // 2\n",
    "                        if nums[i] + nums[c] == target:\n",
    "                            r = c\n",
    "                            break\n",
    "                        elif nums[i] + nums[c] < target:\n",
    "                            l = c + 1\n",
    "                        else:\n",
    "                            r = c - 1\n",
    "                    j = r\n",
    "            return ret\n",
    "\n",
    "        nums = sorted(nums)\n",
    "        ret = []\n",
    "        for i in range(0, len(nums)):\n",
    "            ret.extend(search_2sum(nums[:i], -nums[i]))\n",
    "\n",
    "        ret = sorted(ret)\n",
    "        i = 0\n",
    "        for j in range(len(ret)):\n",
    "            if j and ret[j] == ret[j - 1]:\n",
    "                pass\n",
    "            else:\n",
    "                ret[i] = ret[j]\n",
    "                i += 1\n",
    "\n",
    "        # print(ret[:i])\n",
    "        return ret[:i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#\r\n",
    "# @lc app=leetcode.cn id=15 lang=python3\r\n",
    "#\r\n",
    "# [15] 三数之和\r\n",
    "#\r\n",
    "# https://leetcode-cn.com/problems/3sum/description/\r\n",
    "#\r\n",
    "# algorithms\r\n",
    "# Medium (20.97%)\r\n",
    "# Total Accepted:    38K\r\n",
    "# Total Submissions: 181K\r\n",
    "# Testcase Example:  '[-1,0,1,2,-1,-4]'\r\n",
    "#\r\n",
    "# 给定一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，使得 a + b + c = 0\r\n",
    "# ？找出所有满足条件且不重复的三元组。\r\n",
    "# \r\n",
    "# 注意：答案中不可以包含重复的三元组。\r\n",
    "# \r\n",
    "# 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，\r\n",
    "# \r\n",
    "# 满足要求的三元组集合为：\r\n",
    "# [\r\n",
    "# ⁠ [-1, 0, 1],\r\n",
    "# ⁠ [-1, -1, 2]\r\n",
    "# ]\r\n",
    "# \r\n",
    "# \r\n",
    "#\r\n",
    "class Solution:\r\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\r\n",
    "        nums = sorted(nums)\r\n",
    "        l = len(nums)\r\n",
    "        r = set()\r\n",
    "        for c in range(l):\r\n",
    "            a = c+1\r\n",
    "            b = l-1\r\n",
    "            sum = -nums[c]\r\n",
    "\r\n",
    "            while a < b:\r\n",
    "                if nums[a] + nums[b] > sum:\r\n",
    "                    b -= 1\r\n",
    "                elif nums[a] + nums[b] < sum:\r\n",
    "                    a += 1\r\n",
    "                else:\r\n",
    "                    r.add(tuple(sorted([nums[a],nums[b],nums[c]])))\r\n",
    "                    a += 1\r\n",
    "                    b -= 1\r\n",
    "\r\n",
    "        return [list(t) for t in r]\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        \r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        d = {}\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        nums = sorted(nums)\n",
    "        for i , number in enumerate(nums):\n",
    "            j = i + 1\n",
    "            l = len(nums) - 1 \n",
    "            while j < l:\n",
    "                sum = nums[i] + nums[j] + nums[l]\n",
    "                if sum > 0:\n",
    "                    l = l - 1\n",
    "                elif sum < 0 :\n",
    "                    j = j + 1\n",
    "                else:\n",
    "                    t =  (nums[i],nums[j],nums[l])\n",
    "                    if t not in d:\n",
    "                        d[t] = 1\n",
    "                    if nums[j]==nums[l]:\n",
    "                        break\n",
    "                    l = l - 1\n",
    "                    j = j + 1\n",
    "                    \n",
    "        return [*map(list,d.keys()) ]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        dataList = sorted(nums)\n",
    "        result = set([])\n",
    "        for index in range(len(dataList)-2):\n",
    "            index1 = index+1\n",
    "            index2 = len(dataList)-1\n",
    "            if dataList[index]>0:\n",
    "                break\n",
    "            if index>0 and dataList[index]==dataList[index-1]:\n",
    "                continue\n",
    "            while index1<index2:\n",
    "                sum_2 = dataList[index1]+dataList[index2]\n",
    "                if dataList[index]+dataList[index1]>0:\n",
    "                    break\n",
    "                if sum_2==-dataList[index]:\n",
    "                    result.add((dataList[index],dataList[index1],dataList[index2]))\n",
    "                    index1+=1\n",
    "                    index2-=1\n",
    "                elif sum_2>-dataList[index]:\n",
    "                    index2-=1\n",
    "                else:\n",
    "                    index1+=1\n",
    "        return list(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            left, right = i+1, n-1\n",
    "            while left < right:\n",
    "                sum_ = nums[i] + nums[left] + nums[right]\n",
    "                ans = [nums[i], nums[left], nums[right]]\n",
    "                if sum_ > 0:\n",
    "                    right -= 1\n",
    "                elif sum_ < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    if ans not in res:\n",
    "                        res.append(ans)\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                return result\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while right > left:\n",
    "                n_sum = nums[i] + nums[left] + nums[right]\n",
    "                if n_sum > 0:\n",
    "                    right -= 1\n",
    "                elif n_sum < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    result.append([nums[i], nums[left], nums[right]])\n",
    "                    while right > left and nums[left] == nums[left + 1]:\n",
    "                        left += 1\n",
    "                    while right > left and nums[right] == nums[right - 1]:\n",
    "                        right -= 1\n",
    "                \n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.track = []\n",
    "        self.rst = []\n",
    "        self.summ = 0\n",
    "\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates, 0, target)\n",
    "        return self.rst\n",
    "    \n",
    "    def backtrack(self, nums, start, target):\n",
    "        if self.summ == target:\n",
    "            self.rst.append(self.track[:])\n",
    "            return \n",
    "        if self.summ > target:\n",
    "            return\n",
    "\n",
    "        for i in range(start, len(nums)):\n",
    "            if i > start and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            self.summ += nums[i]\n",
    "            self.track.append(nums[i])\n",
    "            self.backtrack(nums, i + 1, target)\n",
    "            self.summ -= nums[i]\n",
    "            self.track.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = []\n",
    "        self.track = []\n",
    "        self.tracksum = 0\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates, 0, target)\n",
    "        return self.res\n",
    "    def backtrack(self, nums, start, target):\n",
    "        if self.tracksum == target:\n",
    "            self.res.append(self.track.copy())\n",
    "            return\n",
    "        if self.tracksum > target:\n",
    "            return\n",
    "        for i in range(start, len(nums)):\n",
    "            if i > start and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            self.track.append(nums[i])\n",
    "            self.tracksum += nums[i]\n",
    "            self. backtrack(nums, i + 1, target)\n",
    "            self.tracksum -= nums[i]\n",
    "            self.track.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.res = []\n",
    "        self.track = []\n",
    "        self.track_sum = 0\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates, target, 0)\n",
    "        return self.res\n",
    "\n",
    "    def backtrack(self, candidates, target, start):\n",
    "        if self.track_sum == target:\n",
    "            self.res.append(self.track[:])\n",
    "            return\n",
    "        \n",
    "        if self.track_sum > target:\n",
    "            return \n",
    "        \n",
    "        for i in range(start, len(candidates)):\n",
    "            # 剪枝\n",
    "            if i > start and candidates[i] == candidates[i-1]:\n",
    "                continue\n",
    "\n",
    "            self.track.append(candidates[i])\n",
    "            self.track_sum += candidates[i]\n",
    "\n",
    "            self.backtrack(candidates, target, i+1)\n",
    "\n",
    "            self.track.pop()\n",
    "            self.track_sum -= candidates[i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        res=[]\n",
    "        path=[]\n",
    "        sumval=0\n",
    "        candidates.sort()\n",
    "        n=len(candidates)\n",
    "        def backtrack(res,path,start,n,sumval):\n",
    "            if sumval==target:\n",
    "                res.append(path[:])\n",
    "            if sumval>target:\n",
    "                return\n",
    "            for i in range (start,n):\n",
    "                if i>start and candidates[i]==candidates[i-1]:\n",
    "                    continue\n",
    "                path.append(candidates[i])\n",
    "                sumval+=candidates[i]\n",
    "                backtrack(res,path,i+1,n,sumval)\n",
    "                path.pop()\n",
    "                sumval-=candidates[i]\n",
    "        backtrack(res,path,0,n,sumval)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        res = []\n",
    "        tmp = []\n",
    "        candidates.sort()\n",
    "\n",
    "        def dfs(i, curr_sum):\n",
    "            if curr_sum == target:\n",
    "                res.append(list(tmp))\n",
    "                return\n",
    "\n",
    "            if curr_sum > target or i == len(candidates):\n",
    "                return\n",
    "\n",
    "            j = i\n",
    "            cnt = 0\n",
    "            while j < len(candidates) and candidates[j] == candidates[i]:\n",
    "                j += 1\n",
    "                if curr_sum + candidates[i] <= target:\n",
    "                    tmp.append(candidates[i])\n",
    "                    cnt += 1\n",
    "                    curr_sum += candidates[i]\n",
    "        \n",
    "            dfs(j, curr_sum)\n",
    "            for t in range(cnt):\n",
    "                curr_sum -= candidates[i]\n",
    "                tmp.pop()\n",
    "                dfs(j, curr_sum)\n",
    "\n",
    "        dfs(0, 0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        path = []\n",
    "        res = []\n",
    "        vis = [False] * len(candidates)\n",
    "        def backwards(start, sum, candidates):\n",
    "            if sum == target:\n",
    "                res.append(path[:])\n",
    "                return\n",
    "            for i in range(start, len(candidates)):\n",
    "                if i > 0 and candidates[i] == candidates[i-1] and not vis[i - 1]:\n",
    "                    continue\n",
    "                sum += candidates[i]\n",
    "                if sum <= target:\n",
    "                    path.append(candidates[i])\n",
    "                    vis[i] = True\n",
    "                    backwards(i+1, sum, candidates)\n",
    "                    path.pop()\n",
    "                    sum -= candidates[i]\n",
    "                    vis[i] = False\n",
    "                else:\n",
    "                    return\n",
    "        backwards(0, 0, candidates)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.res = []\n",
    "        self.track = []\n",
    "        self.track_sum = 0\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates, target, 0)\n",
    "        return self.res\n",
    "\n",
    "    def backtrack(self, candidates, target, start):\n",
    "        if self.track_sum == target:\n",
    "            self.res.append(self.track[:])\n",
    "            return\n",
    "        \n",
    "        if self.track_sum > target:\n",
    "            return \n",
    "        \n",
    "        for i in range(start, len(candidates)):\n",
    "            if i > start and candidates[i] == candidates[i-1]:\n",
    "                continue\n",
    "            self.track.append(candidates[i])\n",
    "            self.track_sum += candidates[i]\n",
    "\n",
    "            self.backtrack(candidates, target, i+1)\n",
    "\n",
    "            self.track.pop()\n",
    "            self.track_sum -= candidates[i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def backtrack(self,starindex,target,candidate,path,res):\n",
    "        if sum(path)==target:\n",
    "            if path not in res:\n",
    "                res.append(path[:])\n",
    "            return\n",
    "        \n",
    "        for i in range(starindex,len(candidate)):\n",
    "            if i > starindex and candidate[i] == candidate[i - 1]:  # 处理重复的情况，避免重复组合\n",
    "                continue\n",
    "\n",
    "\n",
    "            if sum(path)>target:\n",
    "                break\n",
    "            path.append(candidate[i])\n",
    "            \n",
    "            \n",
    "            self.backtrack(i+1,target,candidate,path,res)\n",
    "            path.pop()\n",
    "        return res\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "    \n",
    "        res=self.backtrack(0,target,candidates,[],[])\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.res  = []\n",
    "        track = []\n",
    "        candidates = sorted(candidates)\n",
    "        numsum =0\n",
    "        start = 0\n",
    "        used = [False]*len(candidates)\n",
    "        self.trackback(candidates, target, track, numsum,start,used)\n",
    "        return self.res\n",
    "\n",
    "    def trackback(self, candidates,target,track,numsum,start,used):\n",
    "        if numsum == target:\n",
    "            self.res.append(track[:])\n",
    "            return self.res\n",
    "        if numsum > target:\n",
    "            return\n",
    "        for i in range(start, len(candidates)):\n",
    "            if candidates[i]==candidates[i-1] and i>start and not used[i-1]:\n",
    "                continue\n",
    "            if not used[i]:\n",
    "                used[i] = True\n",
    "                track.append(candidates[i])\n",
    "                numsum+=candidates[i]\n",
    "                self.trackback(candidates, target, track, numsum, i, used)\n",
    "                used[i] = False\n",
    "                track.pop()\n",
    "                numsum-=candidates[i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.track = []\n",
    "        self.res = []\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates,0,target)\n",
    "        return self.res\n",
    "    def backtrack(self,nums,start,target):\n",
    "        # base case\n",
    "        if sum(self.track)==target:\n",
    "            self.res.append(self.track[:])\n",
    "            return \n",
    "        # base case\n",
    "        # 关键一步 大于目标值的路径没必要继续遍历\n",
    "        if sum(self.track) > target:\n",
    "            return\n",
    "\n",
    "        for i in range(start,len(nums)):\n",
    "            if i>start and nums[i-1]==nums[i]:\n",
    "                continue\n",
    "            self.track.append(nums[i])\n",
    "            self.backtrack(nums,i+1,target)\n",
    "            self.track.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates, target: int):\n",
    "        ans=[]\n",
    "        path=[]\n",
    "        candidates.sort()\n",
    "        def dfs(i):\n",
    "            if sum(path)==target and path not in ans:\n",
    "                ans.append(path.copy())\n",
    "                return\n",
    "            elif sum(path)>target:\n",
    "                return\n",
    "            else:\n",
    "                for j in range(i,len(candidates)):\n",
    "                    if j>i and candidates[j]==candidates[j-1]:\n",
    "                        continue\n",
    "                    #path.append(candidates[i])错误写法，动态变换的索引是j\n",
    "                    path.append(candidates[j])\n",
    "                    dfs(j+1)\n",
    "                    path.pop()\n",
    "        dfs(0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        n = len(candidates)\n",
    "        path = []\n",
    "        res = []\n",
    "        def dfs(depth):\n",
    "            if sum(path) == target:\n",
    "                res.append(path[:])\n",
    "                return\n",
    "            for i in range(depth, n):\n",
    "                if i > depth and candidates[i] == candidates[i-1]:\n",
    "                    continue\n",
    "                path.append(candidates[i])\n",
    "                if sum(path) > target:\n",
    "                    path.pop()\n",
    "                    return\n",
    "                dfs(i+1)\n",
    "                path.pop()\n",
    "        dfs(0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        path = []\n",
    "        ans = []\n",
    "        sums = 0\n",
    "        candidates.sort()\n",
    "        n = len(candidates)\n",
    "        b = False \n",
    "        def dfs(i:int):\n",
    "            nonlocal sums\n",
    "            nonlocal b\n",
    "            if sums > target:\n",
    "                return\n",
    "            elif sums == target:\n",
    "                ans.append(path.copy())\n",
    "                return \n",
    "            for j in range(i,n):\n",
    "                if b and j > 0 and candidates[j] == candidates[j-1]:\n",
    "                    continue\n",
    "                b = False\n",
    "                path.append(candidates[j])\n",
    "                sums += candidates[j]\n",
    "                dfs(j+1)\n",
    "                if sums >= target:\n",
    "                    sums -= path.pop()\n",
    "                    b = True\n",
    "                    return \n",
    "                sums -= path.pop()\n",
    "                b = True\n",
    "        dfs(0)\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "\n",
    "\n",
    "        path = [] \n",
    "        res = [] \n",
    "\n",
    "        candidates.sort() \n",
    "\n",
    "        vis = [False for i in range(len(candidates))]\n",
    "\n",
    "        def backward(start,sum,candidates):\n",
    "            # 返回条件 1、相等  2、 sum> target 没有＋的必要了\n",
    "\n",
    "\n",
    "            if sum == target:\n",
    "                res.append(path[:])\n",
    "                return \n",
    "            for i in range(start,len(candidates)):\n",
    "                #   避免 1 ，1 这种反复计算，但是保留 1+1的情况\n",
    "                if i > 0  and candidates[i] == candidates[i-1] and not vis[i-1]:\n",
    "\n",
    "                    continue \n",
    "\n",
    "                sum += candidates[i]\n",
    "                if sum<=target:\n",
    "                    vis[i] = True \n",
    "                    path.append(candidates[i])\n",
    "\n",
    "                    backward(i+1,sum,candidates)\n",
    "\n",
    "                    path.pop() \n",
    "                    \n",
    "                    vis[i] = False\n",
    "                    sum-=candidates[i]\n",
    "                else:\n",
    "                    return \n",
    "        backward(0,0,candidates)\n",
    "        return res\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        # load = []\n",
    "        n = len(candidates)\n",
    "        nums = candidates\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        def dfs(i, load, tar):\n",
    "            # nonlocal load\n",
    "            if tar == 0:\n",
    "                # print(load)\n",
    "                res.append(load)\n",
    "                return\n",
    "            for j in range(i, n):\n",
    "                if j > i and nums[j] == nums[j - 1]:\n",
    "                    continue\n",
    "                if tar - nums[j] < 0:\n",
    "                    break\n",
    "                # load.append(nums[j])\n",
    "                dfs(j + 1, load + [nums[j]], tar - nums[j])\n",
    "                # load.pop()\n",
    "        dfs(0, [], target)\n",
    "        return res\n",
    "        \n",
    "#         dp = []\n",
    "#         # dp = [target for i in range(len(candidates))]\n",
    "#         def traverse(index, load, sums):\n",
    "#             # print(load)\n",
    "#             if index >= len(candidates):\n",
    "#                 return\n",
    "#             if sums > target:\n",
    "#                 return\n",
    "#             if sums == target:\n",
    "#                 # if load == [1, 2, 5]:\n",
    "#                 print(load)\n",
    "#                 if load not in dp:\n",
    "#                     dp.append(load)\n",
    "#                 return\n",
    "#             tmp1 = copy.deepcopy(load)\n",
    "#             tmp1.append(candidates[index])\n",
    "#             tmp2 = copy.deepcopy(load)\n",
    "#             traverse(index+1, tmp1, sums+candidates[index])\n",
    "            \n",
    "#             traverse(index+1, tmp2, sums)\n",
    "#             return\n",
    "\n",
    "#         for index in range(len(candidates)):\n",
    "#             load = []\n",
    "#             sums = 0\n",
    "#             final = traverse(index, load, sums)\n",
    "#             # if final not in memo:\n",
    "#             #     memo.append(final)\n",
    "#             # # return memo\n",
    "#             # print(final)\n",
    "#         print(dp)\n",
    "#         return dp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        if not candidates:\n",
    "            return []\n",
    "\n",
    "        self.target = target\n",
    "        candidates.sort()\n",
    "        self.track = []\n",
    "        self.res = []\n",
    "        self.bt(candidates, 0, 0)\n",
    "        return self.res\n",
    "\n",
    "    def bt(self, candidates, start, sum):\n",
    "        if sum == self.target:\n",
    "            self.res.append(self.track[:])\n",
    "            return\n",
    "        if start == len(candidates):\n",
    "            return\n",
    "        for i in range(start, len(candidates)):\n",
    "            if i > start and candidates[i] == candidates[i-1]:\n",
    "                continue\n",
    "            item = candidates[i]\n",
    "            if sum + item > self.target:\n",
    "                break\n",
    "            self.track.append(item)\n",
    "            sum += item\n",
    "            self.bt(candidates, i+1, sum)\n",
    "            sum -= item\n",
    "            self.track.pop() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        path = []\n",
    "        ans = []\n",
    "        sums = 0\n",
    "        candidates.sort()\n",
    "        n = len(candidates)\n",
    "        b = False \n",
    "        def dfs(i:int):\n",
    "            nonlocal sums\n",
    "            nonlocal b\n",
    "            if sums > target:\n",
    "                return\n",
    "            elif sums == target:\n",
    "                ans.append(path.copy())\n",
    "                return \n",
    "            for j in range(i,n):\n",
    "                if b and j > 0 and candidates[j] == candidates[j-1]:\n",
    "                    continue\n",
    "                b = False\n",
    "                path.append(candidates[j])\n",
    "                sums += candidates[j]\n",
    "                dfs(j+1)\n",
    "                if sums >= target:\n",
    "                    sums -= path.pop()\n",
    "                    # b = True\n",
    "                    return \n",
    "                sums -= path.pop()\n",
    "                b = True\n",
    "        dfs(0)\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        result=[]\n",
    "\n",
    "        def backtrack(start,sub_result,all_sum):\n",
    "            if all_sum==target:\n",
    "                result.append(sub_result[:])\n",
    "                return\n",
    "            if all_sum>target:\n",
    "                return\n",
    "            \n",
    "            for i in range(start,len(candidates)):\n",
    "                if i>start and candidates[i]==candidates[i-1]:\n",
    "                    continue\n",
    "                sub_result.append(candidates[i])\n",
    "                all_sum+=candidates[i]\n",
    "                backtrack(i+1,sub_result,all_sum)\n",
    "                sub_result.pop()\n",
    "                all_sum-=candidates[i]\n",
    "        backtrack(0,[],0)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def process(self, sum, startidx):\n",
    "        if sum == self.target:\n",
    "            self.result.append(self.tmp[:])\n",
    "            return\n",
    "        if sum > self.target:\n",
    "            return\n",
    "\n",
    "        for i in range(startidx, self.length):\n",
    "            if (i>0) and (self.candidates[i] == self.candidates[i-1]) and (not self.used[i-1]):\n",
    "                continue\n",
    "            self.tmp.append(self.candidates[i])\n",
    "            self.used[i] = True\n",
    "            self.process(sum+self.candidates[i], i+1)\n",
    "            self.tmp.pop()\n",
    "            self.used[i] = False\n",
    "    \n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.tmp = []\n",
    "        self.result = []\n",
    "        self.used = []\n",
    "        self.length = len(candidates)\n",
    "        self.target = target\n",
    "        self.candidates = candidates\n",
    "        self.candidates.sort()\n",
    "        print(self.candidates)\n",
    "        for i in range(self.length):\n",
    "            self.used.append(False)\n",
    "\n",
    "        self.process(0, 0)\n",
    "\n",
    "        return self.result\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        \n",
    "        if len(candidates) == 0:\n",
    "            return []\n",
    "        nums = sorted(candidates)\n",
    "        \n",
    "        path = []\n",
    "        reslist = []\n",
    "        used = [False] * len(nums)\n",
    "        def backtracking(startindex, cursum):\n",
    "            \n",
    "            if cursum == target:\n",
    "                reslist.append(path[:])\n",
    "                return\n",
    "            if startindex >= len(nums)  or cursum > target:\n",
    "                return\n",
    "\n",
    "            for i in range(startindex, len(nums)):\n",
    "                if i - 1 >= 0 and nums[i] == nums[i - 1] and used[i - 1] == False:\n",
    "                    continue\n",
    "                path.append(nums[i])\n",
    "                cursum += nums[i]\n",
    "                used[i] = True\n",
    "                backtracking(i + 1, cursum)\n",
    "                path.pop()\n",
    "                cursum -= nums[i]\n",
    "                used[i] = False\n",
    "            return\n",
    "        \n",
    "        backtracking(0, 0)\n",
    "        return reslist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def process(self, sum, startidx):\n",
    "        if sum == self.target:\n",
    "            self.result.append(self.tmp[:])\n",
    "            return\n",
    "        if sum > self.target:\n",
    "            return\n",
    "\n",
    "        for i in range(startidx, self.length):\n",
    "            if (i>0) and (self.candidates[i] == self.candidates[i-1]) and (not self.used[i-1]):\n",
    "                continue\n",
    "            self.tmp.append(self.candidates[i])\n",
    "            self.used[i] = True\n",
    "            self.process(sum+self.candidates[i], i+1)\n",
    "            self.tmp.pop()\n",
    "            self.used[i] = False\n",
    "    \n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.tmp = []\n",
    "        self.result = []\n",
    "        self.used = []\n",
    "        self.length = len(candidates)\n",
    "        self.target = target\n",
    "        self.candidates = candidates\n",
    "        self.candidates.sort()\n",
    "        print(self.candidates)\n",
    "        for i in range(self.length):\n",
    "            self.used.append(False)\n",
    "\n",
    "        self.process(0, 0)\n",
    "\n",
    "        return self.result\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/hui-su-sua-56e11\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = []\n",
    "        self.track = []\n",
    "\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        self.backtrack(candidates, target, 0)\n",
    "\n",
    "        return self.res\n",
    "\n",
    "    def backtrack(self, candidates, target, start):\n",
    "        # 终止条件做的事\n",
    "        if sum(self.track) == target:\n",
    "            self.res.append(self.track[:])\n",
    "            return\n",
    "        \n",
    "        # 剪枝。这一步也可以不写，但不写会比较耗时，写了就更节约时间\n",
    "        if sum(self.track) > target:\n",
    "            return\n",
    "\n",
    "        # 循环每一个选择\n",
    "        for i in range(start, len(candidates)):\n",
    "            # 剪枝\n",
    "            if i > start and candidates[i] == candidates[i-1]:\n",
    "                continue\n",
    "            # 做选择\n",
    "            self.track.append(candidates[i])\n",
    "            self.backtrack(candidates, target, i + 1)\n",
    "            self.track.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        \n",
    "        if len(candidates) == 0:\n",
    "            return []\n",
    "        nums = sorted(candidates)\n",
    "        \n",
    "        path = []\n",
    "        reslist = []\n",
    "        used = [False] * len(nums)\n",
    "        def backtracking(startindex, cursum):\n",
    "            \n",
    "            if cursum == target:\n",
    "                reslist.append(path[:])\n",
    "                return\n",
    "            if cursum > target: # 注意要加cursum > target 的判断，否则会超时\n",
    "                return\n",
    "\n",
    "            for i in range(startindex, len(nums)):\n",
    "                if i - 1 >= 0 and nums[i] == nums[i - 1] and used[i - 1] == False:\n",
    "                    continue\n",
    "                path.append(nums[i])\n",
    "                cursum += nums[i]\n",
    "                used[i] = True\n",
    "                backtracking(i + 1, cursum)\n",
    "                path.pop()\n",
    "                cursum -= nums[i]\n",
    "                used[i] = False\n",
    "            return\n",
    "        \n",
    "        backtracking(0, 0)\n",
    "        return reslist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "\n",
    "        res = []\n",
    "        def backtrace(paths, index):\n",
    "            if sum(paths) == target:\n",
    "                res.append(paths)\n",
    "                return\n",
    "            if sum(paths) > target:\n",
    "                return\n",
    "            for i in range(index, len(candidates)):\n",
    "                if i> index and candidates[i] == candidates[i-1]:\n",
    "                    continue\n",
    "                backtrace(paths + [candidates[i]], i+1)\n",
    "        backtrace([], 0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.res, n = [], len(candidates)\n",
    "        candidates = sorted(candidates)\n",
    "        temp, temp_sum = [0]*n, 0\n",
    "\n",
    "        def bt(idx, ava, temp_sum):\n",
    "            if idx==n: return True\n",
    "            for i in range(ava, n):\n",
    "                # 因为已经排序，所以后一层选择的数一定大于前一层（保证了解排列单调增）\n",
    "                # 因此在同一层中（一个i循环）选择同样大小的数对应了相同的最终结果，去重即同样的数在同一层只排列一次，不影响相同数多层重复\n",
    "                if i>ava and candidates[i]==candidates[i-1]: continue\n",
    "                temp[idx] = candidates[i]\n",
    "                if temp_sum+candidates[i]==target: self.res.append(temp[:idx+1])\n",
    "                # 有序数组剪枝\n",
    "                elif temp_sum+candidates[i]>target: break\n",
    "                bt(idx+1, i+1, temp_sum+candidates[i])\n",
    "                # 引入temp_sum避免反复求和\n",
    "\n",
    "        bt(0, 0, 0)\n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        nums=[]\n",
    "        cur=0\n",
    "        for i in candidates:\n",
    "            if i==cur:\n",
    "                nums[-1][1]+=1\n",
    "            else:\n",
    "                nums.append([i,1])\n",
    "                cur=i\n",
    "\n",
    "        squence=[]\n",
    "        res=[]\n",
    "\n",
    "        # print(nums)\n",
    "        def dfs(index,sum_val):\n",
    "            nonlocal squence\n",
    "            nonlocal res\n",
    "            if sum_val==target:\n",
    "                res.append(squence[:])\n",
    "            if index==len(nums) or sum_val+nums[index][0]>target:\n",
    "                return\n",
    "            \n",
    "            for i in range(nums[index][1]):\n",
    "                squence.append(nums[index][0])\n",
    "                dfs(index+1,sum_val+(i+1)*nums[index][0])\n",
    "            squence=squence[:-nums[index][1]]\n",
    "\n",
    "            dfs(index+1,sum_val)\n",
    "            return\n",
    "        dfs(0,0)\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        num=len(candidates)\n",
    "        candidates.sort()\n",
    "        res=[]\n",
    "        if sum(candidates)<target:\n",
    "            return []\n",
    "        elif sum(candidates)==target:\n",
    "            return [candidates]\n",
    "        def dfs(s,n):\n",
    "            if sum(s)>target or n==num:\n",
    "                if sum(s)==target:\n",
    "                    if s not in res:\n",
    "                        res.append(s)\n",
    "                return\n",
    "            if sum(s)==target:\n",
    "                if s not in res:\n",
    "                    res.append(s)\n",
    "                return\n",
    "            for i in range(n,num):\n",
    "                dfs(s+[candidates[i]],i+1)\n",
    "        dfs([],0)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        self.res = []\n",
    "        self.path = []\n",
    "        candidates.sort()\n",
    "        self.used = [0 for _ in range(len(candidates))]\n",
    "\n",
    "        def poor(candidates, target, sums, idx, used):\n",
    "            if sums > target:\n",
    "                return \n",
    "            if sums == target:\n",
    "                self.res.append(self.path.copy())\n",
    "\n",
    "            for i in range(idx, len(candidates)):\n",
    "                if i > 0 and candidates[i] == candidates[i - 1] and not self.used[i - 1]:\n",
    "                    continue\n",
    "                self.path.append(candidates[i])\n",
    "                self.used[i] = 1\n",
    "                poor(candidates, target, sums + candidates[i], i + 1, self.used)\n",
    "                self.used[i] = 0\n",
    "                self.path.pop()\n",
    "\n",
    "        poor(candidates, target, 0, 0, self.used)\n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates=sorted(candidates)\n",
    "        path,res=[],[]\n",
    "        def dfs(startindex):\n",
    "            if sum(path)>target:\n",
    "                return\n",
    "            elif sum(path)==target:\n",
    "                res.append(path.copy())\n",
    "                return\n",
    "            set1=set()\n",
    "            for i in range(startindex,len(candidates)):\n",
    "                if candidates[i] in set1:\n",
    "                    continue\n",
    "                set1.add(candidates[i])\n",
    "                path.append(candidates[i])\n",
    "                dfs(i+1)\n",
    "                path.pop()\n",
    "        dfs(0)\n",
    "        return res\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        results = []\n",
    "\n",
    "        candidates.sort()\n",
    "        print(candidates)\n",
    "        def dfs(paths, index):\n",
    "            if sum(paths) == target:# and sorted(paths) not in results:\n",
    "                results.append(paths)\n",
    "                return\n",
    "            if sum(paths)> target:\n",
    "                return\n",
    "\n",
    "            for i in range(index, len(candidates)):\n",
    "                if i> index and candidates[i] in candidates[index:i]:\n",
    "                    continue\n",
    "                dfs(paths +[candidates[i]], i+1)\n",
    "\n",
    "        dfs([], 0)\n",
    "        print(results)\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        n_list = []\n",
    "        result = []\n",
    "        candidates.sort()\n",
    "\n",
    "        def dfs(i):\n",
    "            if i == len(candidates):\n",
    "                return\n",
    "            n_list.append(candidates[i])\n",
    "            sum_n = sum(n_list)\n",
    "            if sum_n == target:\n",
    "                result.append(n_list.copy())\n",
    "            elif sum_n < target:\n",
    "                j = i + 1\n",
    "                while j < len(candidates):\n",
    "                    dfs(j)\n",
    "                    j += 1\n",
    "                    while j < len(candidates) and candidates[j] == candidates[j-1]:\n",
    "                        j += 1\n",
    "            n_list.pop()\n",
    "\n",
    "        for i in range(0, len(candidates)):\n",
    "            if i != 0 and candidates[i] == candidates[i-1]:\n",
    "                continue\n",
    "            dfs(i)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates.sort()\n",
    "        n = len(candidates)\n",
    "        ans =[]\n",
    "        path =[] \n",
    "        \n",
    "\n",
    "        def dfs(i):\n",
    "            if sum(path)==target:\n",
    "                path.sort()\n",
    "                ans.append(path.copy())\n",
    "                return\n",
    "            if sum(path)>target:\n",
    "                return\n",
    "\n",
    "            for j in range(i,n):\n",
    "                if candidates[j]==candidates[j-1] and j-1>=i:\n",
    "                    continue\n",
    "                path.append(candidates[j])\n",
    "                dfs(j+1)\n",
    "                path.pop() #恢复现场\n",
    "\n",
    "        dfs(0)\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        def dfs(idx, s):\n",
    "            if s > target or s + sum(candidates[idx:]) < target:\n",
    "                return\n",
    "            if s == target:\n",
    "                res.add(tuple(path[:]))\n",
    "                return\n",
    "            path.append(candidates[idx])\n",
    "            dfs(idx+1, s+candidates[idx])\n",
    "            path.pop(-1)\n",
    "            dfs(idx+1, s)\n",
    "        res = set()\n",
    "        path = []\n",
    "        l = len(candidates)\n",
    "        candidates = sorted(candidates)\n",
    "        dfs(0, 0)\n",
    "        return list(map(list, res))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        nums.sort()\n",
    "        numsLen=len(nums)\n",
    "        ans=[]\n",
    "        for i in range(numsLen-3):\n",
    "            for j in range(i+1,numsLen): #3 sum\n",
    "                s=j+1\n",
    "                e=len(nums)-1\n",
    "                while s<e:\n",
    "                    sum=nums[i]+nums[j]+nums[s]+nums[e]\n",
    "                    if sum==target:\n",
    "                        list=[nums[i],nums[j],nums[s],nums[e]]\n",
    "                        if list not in ans:\n",
    "                            ans.append(list)\n",
    "                        s+=1\n",
    "                        e-=1\n",
    "                    elif sum<target:\n",
    "                        s+=1\n",
    "                    else:\n",
    "                        e-=1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        if len(nums) < 4:\n",
    "            return []\n",
    "\n",
    "        nums = sorted(nums)\n",
    "        outs = []\n",
    "        i = 0\n",
    "        while i < len(nums) - 3:\n",
    "            j = len(nums) - 1\n",
    "\n",
    "            while j > i + 2:\n",
    "                k = i + 1\n",
    "                w = j - 1\n",
    "                while k < w:\n",
    "                    sums = nums[i] + nums[j] + nums[k] + nums[w]\n",
    "                    if sums < target:\n",
    "                        k += 1\n",
    "                    elif sums > target:\n",
    "                        w -= 1\n",
    "                    else:\n",
    "                        outs.append([nums[i], nums[k], nums[w], nums[j]])\n",
    "                        k += 1\n",
    "                        w -= 1\n",
    "                        while k < w and nums[k] == nums[k - 1]:\n",
    "                            k += 1\n",
    "                        while k < w and nums[w] == nums[w + 1]:\n",
    "                            w -= 1\n",
    "\n",
    "                j -= 1\n",
    "                while j > i + 2 and nums[j] == nums[j + 1]:\n",
    "                    j -= 1\n",
    "            i += 1\n",
    "            while i < len(nums) - 3 and nums[i - 1] == nums[i]:\n",
    "                i += 1\n",
    "        return outs\n",
    "\n",
    "\n",
    "s = Solution()\n",
    "# print(s.fourSum([1, 0, -1, 0, -2, 2], 0))\n",
    "print(s.fourSum([-3, -1, 0, 2, 4, 5], 2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        def findNsum(l, r, target, N, result, results):\n",
    "            if r-l+1 < N or N < 2 or target < nums[l]*N or target > nums[r]*N:  # early termination\n",
    "                return\n",
    "            if N == 2: # two pointers solve sorted 2-sum problem\n",
    "                while l < r:\n",
    "                    s = nums[l] + nums[r]\n",
    "                    if s == target:\n",
    "                        results.append(result + [nums[l], nums[r]])\n",
    "                        l += 1\n",
    "                        r -= 1\n",
    "                        while l < r and nums[l] == nums[l - 1]:\n",
    "                            l += 1\n",
    "                        while r > l and nums[r] == nums[r + 1]:\n",
    "                            r -= 1\n",
    "                    elif s < target:\n",
    "                        l += 1\n",
    "                    else:\n",
    "                        r -= 1\n",
    "            else: # recursively reduce N\n",
    "                for i in range(l, r+1):\n",
    "                    if i == l or (i > l and nums[i-1] != nums[i]):\n",
    "                        findNsum(i+1, r, target-nums[i], N-1, result+[nums[i]], results)\n",
    "\n",
    "        nums.sort()\n",
    "        results = []\n",
    "        findNsum(0, len(nums)-1, target, 4, [], results)\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        for i in range(len(nums) - 3):\n",
    "            if i and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            for j in range(i + 1, len(nums) - 2):\n",
    "                if j != i + 1 and nums[j] == nums[j - 1]:\n",
    "                    continue\n",
    "                sum = target - nums[i] - nums[j]\n",
    "                left, right = j + 1, len(nums) - 1\n",
    "                while left < right:\n",
    "                    if nums[left] + nums[right] == sum:\n",
    "                        res.append([nums[i], nums[j], nums[left], nums[right]])\n",
    "                        right -= 1\n",
    "                        left += 1\n",
    "                        while left < right and nums[left] == nums[left - 1]:\n",
    "                            left += 1\n",
    "                        while left < right and nums[right] == nums[right + 1]:\n",
    "                            right -= 1\n",
    "                    elif nums[left] + nums[right] > sum:\n",
    "                        right -= 1\n",
    "                    else:\n",
    "                        left += 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        res = []\n",
    "        nums.sort()\n",
    "        #这种求和为了减少步骤首先是排序比较  哎哎哎\n",
    "        a = nums[:4]\n",
    "        if sum(nums[:4]) > target:\n",
    "            return res\n",
    "        for index, num in enumerate(nums[:-3]):\n",
    "            target1 = target - num\n",
    "            if sum(nums[index: index + 4]) > target:\n",
    "                break\n",
    "                #下面的条件是最后的三个数比target1还小就是在target1固定的情况下达不到目标了\n",
    "                #或者是我现在的数和我上一次的数相同  确实 这种情况下不进行下一个循环就会重复\n",
    "                #记住 这个条件总的就是 要么达不到 要么会重复所以跳过\n",
    "            elif sum(nums[-3:]) < target1 or (index > 0 and num == nums[index - 1]):\n",
    "                continue\n",
    "                #在固定第一个后第二个数进行循环 因为是四个数所以截止到倒数第三个\n",
    "            for j in range(index + 1, len(nums) - 2):\n",
    "                target2 = target1 - nums[j]\n",
    "                #同样的道理 两种情况剔除\n",
    "                if nums[j + 1] + nums[j + 2] > target2:\n",
    "                    break\n",
    "                elif nums[-2] + nums[-1] < target2 or (j > index + 1 and nums[j] == nums[j - 1]):\n",
    "                    continue\n",
    "                    #再把特殊情况剔除后达到我们最后两个数的和等于目标  用双指针法  但为什么这么写会快很多啊 不是很懂 ：（\n",
    "                l, r = j + 1, len(nums) - 1\n",
    "                while l < r:\n",
    "                    temp = nums[l] + nums[r]\n",
    "                    if temp > target2:\n",
    "                        r -= 1\n",
    "                    elif temp < target2:\n",
    "                        l += 1\n",
    "                    else:\n",
    "                        res.append([num, nums[j], nums[l], nums[r]])\n",
    "                        while l < r and nums[l] == nums[l + 1]:\n",
    "                            l += 1\n",
    "                        while l < r and nums[r] == nums[r - 1]:\n",
    "                            r -= 1\n",
    "                        #相等之后确实两面都要移  不然会重复 因为这两个数相等的结果都有了\n",
    "                        l += 1\n",
    "                        r -= 1\n",
    "        return res  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        res=[]\n",
    "        nums.sort()\n",
    "        print('#')\n",
    "        for i in range(len(nums)-3):\n",
    "            print(i)\n",
    "            # if nums[i]==nums[i+1]:continue\n",
    "            for j in range(i+1,len(nums)-2):\n",
    "                # if nums[j]==nums[j+1]:continue\n",
    "                l=j+1;r=len(nums)-1;\n",
    "                while(l<r):\n",
    "                    sum=nums[i]+nums[j]+nums[l]+nums[r]\n",
    "                    if sum==target:\n",
    "                        ans=[nums[i],nums[j],nums[l],nums[r]]\n",
    "                        if ans not in res:\n",
    "                            res.append(ans)\n",
    "                        l+=1\n",
    "                        r-=1\n",
    "                    elif sum<target:\n",
    "                        l+=1\n",
    "                    else:\n",
    "                        r-=1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        nums.sort()\n",
    "        result = set()\n",
    "        sum_of_two = {}\n",
    "        len_of_nums = len(nums)\n",
    "        if len_of_nums<4:\n",
    "            return []\n",
    "        sum_ij_min = nums[0] + nums[1]\n",
    "        sum_ij_threshold = target - sum_ij_min\n",
    "        sum_of_two[sum_ij_min] = [[0,1]]\n",
    "        for i in range(len_of_nums):\n",
    "            for j in range(i+1,len_of_nums):\n",
    "                if i==0 and j==1:\n",
    "                    continue\n",
    "                sum_ij = nums[i]+nums[j]\n",
    "                if sum_ij > sum_ij_threshold:\n",
    "                    break\n",
    "                key_list = sum_of_two.keys()\n",
    "                if sum_ij not in key_list:\n",
    "                    sum_of_two[sum_ij] = [[i,j]]\n",
    "                else:\n",
    "                    sum_of_two[sum_ij].append([i,j])\n",
    "                if target-sum_ij in key_list:\n",
    "                    for xy in sum_of_two[target-sum_ij]:\n",
    "                        if i not in xy and j not in xy:\n",
    "                            result.add(tuple(sorted([nums[xy[0]],nums[xy[1]],nums[i],nums[j]])))\n",
    "        return list(result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "\n",
    "        ij_dict = dict()\n",
    "        res_set = set()\n",
    "        for i in range(length - 1):\n",
    "            for j in range(i+1, length):\n",
    "\n",
    "                ij_sum = nums[i] + nums[j]\n",
    "                m = target - ij_sum\n",
    "                if m in ij_dict:\n",
    "                    for item in ij_dict[m]:\n",
    "                        if item[1] < i:\n",
    "                            res_set.add((nums[item[0]], nums[item[1]], nums[i], nums[j]))\n",
    "\n",
    "                if ij_sum not in ij_dict:\n",
    "                    ij_dict[ij_sum] = [(i, j)]\n",
    "                else:\n",
    "                    ij_dict[ij_sum].append((i, j))\n",
    "\n",
    "        return [[item[0], item[1], item[2], item[3]]for item in res_set]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        sum_dic = collections.defaultdict(list)\n",
    "        res_set = set()\n",
    "        for i in range(len(nums)-1):\n",
    "            for j in range(i+1, len(nums)):\n",
    "                sum_dic[nums[i]+nums[j]].append((i, j))\n",
    "        for key in sum_dic.keys():\n",
    "            left_key = target-key\n",
    "            if left_key in sum_dic.keys():\n",
    "                for (i, j) in sum_dic[key]:\n",
    "                    for (k, l) in sum_dic[left_key]:\n",
    "                        if i != k and i != l and j != k and j != l:\n",
    "                            res_set.add(tuple(sorted([nums[i], nums[j], nums[k], nums[l]])))\n",
    "        return list(res_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        numsLen = len(nums)\n",
    "        ret = []\n",
    "        if sum(nums[:4]) > target or numsLen < 4:\n",
    "            return []\n",
    "\n",
    "        for one in range(numsLen-3):\n",
    "            # 当值重复时，忽略\n",
    "            if one > 0 and nums[one] == nums[one-1]:\n",
    "                continue\n",
    "\n",
    "            min1 = nums[one] + nums[one+1] + nums[one+2] + nums[one+3]\n",
    "            # 数组4数和的最小值若大于目标值，其后没戏\n",
    "            if min1 > target:\n",
    "                continue\n",
    "\n",
    "            max1 = nums[one] + nums[numsLen-3] + nums[numsLen-2] + nums[numsLen-1]\n",
    "            # 数组4数和的最大值都小于目标值，没戏\n",
    "            if max1 < target:\n",
    "                continue\n",
    "\n",
    "            for two in range(one+1, numsLen-2):\n",
    "                if two > one+1 and nums[two] == nums[two-1]:\n",
    "                    continue\n",
    "                l = two + 1\n",
    "                r = numsLen - 1\n",
    "                min2 = nums[one] + nums[two] + nums[l] + nums[l+1]\n",
    "                if min2 > target:\n",
    "                    continue\n",
    "                max2 = nums[one] + nums[two] + nums[r-1] + nums[r]\n",
    "                if max2 < target:\n",
    "                    continue\n",
    "                while l < r:\n",
    "                    theSum = nums[one] + nums[two] + nums[l] + nums[r]\n",
    "                    if theSum == target:\n",
    "                        ret.append([nums[one], nums[two], nums[l], nums[r]])\n",
    "                        l += 1\n",
    "                        while l < r and nums[l] == nums[l-1]:\n",
    "                            l += 1\n",
    "                        r -= 1\n",
    "                        while l < r and nums[r] == nums[r+1]:\n",
    "                            r -= 1\n",
    "                    elif theSum < target:\n",
    "                        l += 1\n",
    "                    else:\n",
    "                        r -= 1\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        output = []\n",
    "        for i in range(len(nums)):\n",
    "            if (i > 0 and nums[i] == nums[i - 1]):\n",
    "                continue\n",
    "            new_nums = nums[i + 1:]\n",
    "            new_target = target - nums[i]\n",
    "            a = self.threeSum(new_nums, new_target)\n",
    "            if (len(a) == 0):\n",
    "                continue\n",
    "            for k in a:\n",
    "                k.append(nums[i])\n",
    "                output.append(k)\n",
    "        return output\n",
    "                \n",
    "\n",
    "\n",
    "    def threeSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        output = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if (i > 0 and nums[i] == nums[i - 1]):\n",
    "                continue\n",
    "            curridx = i\n",
    "            leftidx = i + 1\n",
    "            rightidx = len(nums) - 1\n",
    "            while (leftidx < rightidx):\n",
    "                sum_ = nums[curridx] + nums[leftidx] + nums[rightidx]\n",
    "                if (sum_ == target):\n",
    "                    output.append([nums[leftidx], nums[curridx], nums[rightidx]])\n",
    "                    leftidx += 1\n",
    "                    while (leftidx < rightidx and nums[leftidx - 1] == nums[leftidx]):\n",
    "                        leftidx += 1\n",
    "                    rightidx -= 1\n",
    "                    while(leftidx < rightidx and nums[rightidx + 1] == nums[rightidx]):\n",
    "                        rightidx -= 1\n",
    "                elif (sum_ < target):\n",
    "                    leftidx += 1\n",
    "                elif (sum_ > target):\n",
    "                    rightidx -= 1\n",
    "            pre = nums[curridx]\n",
    "        return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        nums.sort()\n",
    "        allres = []\n",
    "        for k in range(len(nums)-3):\n",
    "            if k > 0 and nums[k] == nums[k-1]:continue\n",
    "                \n",
    "            for j in range(k+1,len(nums)-2):                                 \n",
    "                l = j+1\n",
    "                r = len(nums)-1\n",
    "                \n",
    "                while l < r and j > k:\n",
    "                    res = sum([nums[k],nums[j],nums[l],nums[r]])\n",
    "                    \n",
    "                    if res > target:\n",
    "                        r -= 1\n",
    "                        while l < r and nums[r] == nums[r+1]: r -= 1\n",
    "                            \n",
    "                    elif res < target:\n",
    "                        l += 1\n",
    "                        while l < r and nums[l] == nums[l-1]: l += 1\n",
    "                            \n",
    "                    else:\n",
    "                        if [nums[k],nums[j],nums[l],nums[r]] not in allres:\n",
    "                            allres.append([nums[k],nums[j],nums[l],nums[r]])\n",
    "                            \n",
    "                        l += 1\n",
    "                        r -= 1\n",
    "                        while l < r and nums[r] == nums[r+1]: r -= 1\n",
    "                        while l < r and nums[l] == nums[l-1]: l += 1   \n",
    "                    \n",
    "        return allres "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        length = len(nums)\n",
    "        re = []\n",
    "        if length < 4:\n",
    "            return re\n",
    "        nums.sort()\n",
    "        for i in range(length - 3):\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                i += 1\n",
    "                continue\n",
    "            for j in range(i + 1, length - 2):\n",
    "                if j > i + 1 and nums[j] == nums[j - 1]:\n",
    "                    j += 1\n",
    "                    continue\n",
    "                p1, p2 = j + 1, length - 1\n",
    "                while p1 < p2:\n",
    "                    sum4 = nums[i] + nums[j] + nums[p1] + nums[p2]\n",
    "                    if sum4 == target:\n",
    "                        re.append([nums[i], nums[j], nums[p1], nums[p2]])\n",
    "                        while p1 < p2 and nums[p1] == nums[p1 + 1]:\n",
    "                            p1 += 1\n",
    "                        while p1 < p2 and nums[p2] == nums[p2 - 1]:\n",
    "                            p2 -= 1\n",
    "                        p1 += 1\n",
    "                        p2 -= 1\n",
    "                    elif sum4 < target:\n",
    "                        p1 += 1\n",
    "                    else:\n",
    "                        p2 -= 1\n",
    "        return re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        n=len(nums)\n",
    "        if n<4:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        res=[]\n",
    "        for i in range(n-3):\n",
    "            if i>0 and nums[i]==nums[i-1]:\n",
    "                continue\n",
    "            for j in range(i+1,n-2):\n",
    "                if j>i+1 and nums[j]==nums[j-1]:\n",
    "                    continue\n",
    "                left,right=j+1,n-1\n",
    "                while left<right:\n",
    "                    four_sum=nums[i]+nums[j]+nums[left]+nums[right]\n",
    "                    if four_sum==target:\n",
    "                        res.append([nums[i],nums[j],nums[left],nums[right]])\n",
    "                        while left<right and nums[left]==nums[left+1]:\n",
    "                            left+=1\n",
    "                        left+=1\n",
    "                        while left<right and nums[right]==nums[right-1]:\n",
    "                            right-=1\n",
    "                        right-=1\n",
    "                    elif four_sum>target:\n",
    "                        right-=1\n",
    "                    else:\n",
    "                        left+=1\n",
    "        return res\n",
    "            \n",
    "                        \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        output = []\n",
    "        \n",
    "        def Search(i, target, oneSolution):\n",
    "\n",
    "            if target == 0 and len(oneSolution) == 4:  # 出口，找到正确的解了\n",
    "                output.append(oneSolution)\n",
    "                return\n",
    "            elif len(oneSolution) > 4 or i >= len(nums):  # 剪枝，超范围了\n",
    "                return\n",
    "            \n",
    "            if target - nums[i] - (3 - len(oneSolution)) * nums[-1] > 0:  # 当前这个数太小了\n",
    "                Search(i + 1, target, oneSolution)\n",
    "            elif target - (4 - len(oneSolution)) * nums[i] < 0:  # 当前组数的和太大了\n",
    "                return\n",
    "            else:  # 当前组数似乎没毛病\n",
    "                Search(i + 1, target, oneSolution)  # 不选这个数\n",
    "                Search(i + 1, target - nums[i], oneSolution + [nums[i]])  # 选这个数\n",
    "\n",
    "        Search(0, target, [])\n",
    "\n",
    "        output1 = []\n",
    "        output2 = []\n",
    "        for t in output:\n",
    "            if set(t) not in output1:\n",
    "                output1.append(set(t))\n",
    "                output2.append(t)\n",
    "\n",
    "        return output2\n",
    "\n",
    "# 作者：flying_du\n",
    "# 链接：https://leetcode-cn.com/problems/4sum/solution/python-wo-jiu-bu-yong-zhi-zhen-fa-zha-di-quan-guo-/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict,Counter\n",
    "class Solution:\n",
    "    def fourSum(self, l: List[int], target: int) -> List[List[int]]:\n",
    "        # 考虑特殊情况\n",
    "        # 如果长度小于4，返回[]\n",
    "        if len(l) < 4:\n",
    "            return []\n",
    "        # 如果等于4，直接相加，是否等于target\n",
    "        if len(l) == 4:\n",
    "            if sum(l) == target:\n",
    "                return [l]\n",
    "            else:\n",
    "                return []\n",
    "        # 如果target 大于 4个大值之和，就返回[]\n",
    "        # 如果target 小于 4个小值之和，就返回[]\n",
    "        l1 = sorted(l)\n",
    "        if target > sum(l1[-4:]):\n",
    "            return []\n",
    "        if target < sum(l1[:4]):\n",
    "            return []\n",
    "\n",
    "        # 一般情况\n",
    "        # 去除一个元素重复多余4次的情况\n",
    "        c = Counter(l)\n",
    "        for k, v in c.items():\n",
    "            if v > 4:\n",
    "                c[k] = 4\n",
    "\n",
    "        # 重新连接成新的数组\n",
    "        l2 = []\n",
    "        for k, v in sorted(c.items(), key=lambda x: x[0]):\n",
    "            l2 += [k] * v\n",
    "\n",
    "        # print(c,l2)\n",
    "\n",
    "        # 定义记录结果的变量\n",
    "        result = []\n",
    "\n",
    "        # 定义一个递归获取的函数\n",
    "        def get(l2, target, p=[], n=0):\n",
    "\n",
    "            # for i,v in enumerate(l2):\n",
    "            #    if n+1 == 4: # 长度等于4，最后一个元素等于target就符合要求\n",
    "            #        if v == target:\n",
    "            #            r = p+[v]\n",
    "            #            if r not in result: # 避免重复\n",
    "            #                result.append(r)\n",
    "            #    else:\n",
    "            #        right = l2[i+1:]\n",
    "            #        if len(right) > 0: # 保证至少还有一个元素，再进入递归\n",
    "            #            get(right,target - v,p+[v],n+1)\n",
    "\n",
    "            for i in range(\n",
    "                len(l2) - 3,\n",
    "            ):\n",
    "                for j in range(i, len(l2)):\n",
    "                    min_ = sum(l2[i : i + 3]) + l2[j]\n",
    "                    max_ = l2[i] + sum(l2[j - 2 : j + 1])\n",
    "                    if not min_ <= target <= max_:\n",
    "                        continue\n",
    "                    else:\n",
    "                        middle = l2[i + 1: j]\n",
    "                        ii = 0\n",
    "                        jj = len(middle)-1\n",
    "                        while ii < jj :\n",
    "                            r = [l2[i],middle[ii],middle[jj],l2[j],]\n",
    "                            if sum(r)>target:\n",
    "                                jj -=1\n",
    "                            elif sum(r) < target:\n",
    "                                ii +=1\n",
    "                            else:\n",
    "                                while True and ii+1 < len(middle):\n",
    "                                    if middle[ii] != middle[ii+1]:\n",
    "                                        ii += 1\n",
    "                                        break\n",
    "                                    ii+=1\n",
    "                                while True and 0 <= jj-1:\n",
    "                                    if middle[jj] != middle[jj-1]:\n",
    "                                        jj -= 1\n",
    "                                        break\n",
    "                                    jj-=1\n",
    "                                if r not in result:\n",
    "                                    result.append(r)\n",
    "\n",
    "\n",
    "        get(\n",
    "            l2,\n",
    "            target,\n",
    "        )\n",
    "\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "    #分治法\n",
    "    #将问题分为若干子问题，对子问题求解后将解合并。\n",
    "    #先将四数和foursum分为；两数和，即twosum(a,threesum(A))，其中a是数组中的任意数，A是除a以外的其他数的集合；\n",
    "    #接下来继续对三数之和进行分解，即twosum(b,twosum(B))。这样就将四数之和转化为了两数之和问题\n",
    "        nums.sort()\n",
    "        results = []\n",
    "        self.findNsum(nums, target, 4, [], results)\n",
    "        return results\n",
    "\n",
    "    def findNsum(\n",
    "        self,\n",
    "        nums: List[int],\n",
    "        target: int,\n",
    "        N: int,\n",
    "        tempList: List[int],\n",
    "        results: List[List[int]],\n",
    "    ) -> None:\n",
    "        if len(nums) < N or N < 2:\n",
    "            return\n",
    "        if N == 2:\n",
    "            l = 0\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                if nums[l] + nums[r] == target:\n",
    "                    results.append(tempList + [nums[l], nums[r]])\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                    # skip duplicated\n",
    "                    while l < r and nums[l] == nums[l - 1]:\n",
    "                        l += 1\n",
    "                    while r > l and nums[r] == nums[r + 1]:\n",
    "                        r -= 1\n",
    "                elif nums[l] + nums[r] < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        # 缩减问题规模\n",
    "        else:\n",
    "            for i in range(0, len(nums)):\n",
    "                # skip duplicated\n",
    "                if i == 0 or i > 0 and nums[i - 1] != nums[i]:\n",
    "                    self.findNsum(\n",
    "                        nums[i + 1 :],\n",
    "                        target - nums[i],\n",
    "                        N - 1,\n",
    "                        tempList + [nums[i]],\n",
    "                        results,\n",
    "                    )\n",
    "        return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        if len(nums)<4:\n",
    "            return []\n",
    "        res=[]\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if i > 0 and nums[i]==nums[i-1]:\n",
    "                continue\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if j > i+1 and nums[j]==nums[j-1]:\n",
    "                    continue\n",
    "                left=j+1\n",
    "                right=len(nums)-1\n",
    "                while left<right:\n",
    "                    if nums[i]+nums[j]+nums[left]+nums[right]<target:\n",
    "                        left+=1\n",
    "                    elif nums[i]+nums[j]+nums[left]+nums[right]> target:\n",
    "                        right-=1\n",
    "                    else:\n",
    "                        res.append([nums[i],nums[j],nums[left],nums[right]])\n",
    "                        left+=1\n",
    "                        right-=1\n",
    "                        while left < right and nums[left]==nums[left-1]:\n",
    "                            left+=1\n",
    "                        while left<right and nums[right]==nums[right+1]:\n",
    "                            right-=1\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        '''n=len(nums)\n",
    "        if n <4:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        res=[]\n",
    "        for i in range(n):\n",
    "            if i>0 and nums[i]==nums[i-1]:\n",
    "                continue\n",
    "            for j in range(i+1,n):\n",
    "                if j >i+1 and nums[j]==nums[j-1]:\n",
    "                    continue\n",
    "                left=j+1\n",
    "                right=n-1\n",
    "                while left<right:\n",
    "                    sum_=nums[i]+nums[j]+nums[left]+nums[right]\n",
    "                    if sum_==target:\n",
    "                        res.append([nums[i],nums[j],nums[left],nums[right]])\n",
    "                        while left<right and nums[left]==nums[left+1]:\n",
    "                            left+=1\n",
    "                        while left<right and nums[right]==nums[right-1]:\n",
    "                            right-=1\n",
    "                        left+=1\n",
    "                        right-=1\n",
    "                    elif sum_<target:\n",
    "                        left+=1\n",
    "                    else:\n",
    "                        right-=1\n",
    "        return res'''\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # sort\n",
    "    # binary search or two pointers to get range of values that work!!!\n",
    "    # [2,3,5,5], target = 6\n",
    "    # 2, search for the first value > 6-2 = 4, which is index 2. sub 1, get index 1 = j\n",
    "    # so anything from index 0...j will work, excluding the current index i\n",
    "    # can also use 2 ptrs\n",
    "    # need to divide by 2 if using binary search, since we compte both sides...\n",
    "    def purchasePlans(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        MOD = 10**9+7\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            j = bisect_right(nums, target-nums[i]) - 1\n",
    "            res += j+1 - (i <= j)\n",
    "        return res // 2 % MOD\n",
    "\n",
    "    def purchasePlans(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        MOD = 10**9+7\n",
    "        n = len(nums)\n",
    "        i = 0\n",
    "        j = n-1\n",
    "        while i < j:\n",
    "            while i < j and nums[i] + nums[j] > target:\n",
    "                j -= 1\n",
    "            res += j-i\n",
    "            i += 1\n",
    "        return res % MOD\n",
    "\n",
    "    def purchasePlans(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        return sum((j := bisect_right(nums, target-nums[i])) - (i < j) for i in range(len(nums))) // 2 % (10**9+7)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def purchasePlans(self, nums: List[int], target: int) -> int:\n",
    "        #巧妙思路:排好序后，一个指针指向第一个，一个指针指向最后一个数组，如果第一个加上最后一个的和都小于目标值，那么中间的值必然都符合并且让第一个指针往后移，例如：2，3，5，5，目标值是7，如果第一个加上最后一个的值是大于目标值的，则让最后一个值的指针往前移\n",
    "        nums.sort()\n",
    "        i=0\n",
    "        j=len(nums)-1\n",
    "        count=0\n",
    "        while i<j:\n",
    "            if nums[i]+nums[j]<=target:\n",
    "                count=count+j-i\n",
    "                i=i+1\n",
    "            else:\n",
    "                j=j-1\n",
    "        return count % 1000000007\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        #这个方法会超时\n",
    "        # sum=0\n",
    "        # for i in range(len(nums)):\n",
    "            \n",
    "        #     for j in range(i+1,len(nums)):\n",
    "               \n",
    "        #         if nums[i]+nums[j]<=target:\n",
    "                    \n",
    "        #             sum=sum+1\n",
    "        #             print(j,sum)\n",
    "                    \n",
    "        # return sum\n",
    "\n",
    "\n",
    "\n",
    "    #         self.bansearch(nums,i+1,n,target-i)\n",
    "    #     return sum\n",
    "\n",
    "\n",
    "    # def bansearch(self,nums,left,right,target1):\n",
    "    #     sum=0\n",
    "    #     while left<=right:\n",
    "    #         mid=(left+right)//2\n",
    "    #         if nums[mid] <= target1:\n",
    "    #            sum=sum+1\n",
    "    #         else:\n",
    "    #             right=mid-1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def numsGame(self, nums: List[int]) -> List[int]:\n",
    "        c = nums.pop(0) + 1#递增序列当前值\n",
    "        s = [0]#差值排序列表\n",
    "        res = [0]\n",
    "        pre = 0#对应之前代码的sum(s[mid:]) - sum(s[:mid])\n",
    "        for i, n in enumerate(nums):\n",
    "            l = i + 2\n",
    "            mid = (i + 1) // 2#中位数下标\n",
    "            idx = bisect.bisect_left(s, n - c)#新元素所在位置\n",
    "            s.insert(idx, n - c)\n",
    "            if i % 2 == 0:#当列表从奇数变为偶数，中位数位置不变\n",
    "                if idx > mid:#如果新元素在中位数右侧，只需要加上新元素其他不变\n",
    "                    pre += n - c\n",
    "                else:#当新元素在中位数左侧，原来的中位数右移，本来是减法现在是加法，所以要加上两倍的原来中位数，新元素在左侧，需要减去\n",
    "                    pre += 2 * s[mid + 1] - (n - c)\n",
    "            else:#当列表从偶数变为奇数，中位数位置+1\n",
    "                if idx > mid:#当新元素在右侧，由于中位数位置+1，原来做加法的元素需要减去两倍，并加上新元素\n",
    "                    pre += n - c - s[mid] * 2\n",
    "                else:#当新元素在左侧时，原来的中位数已经向右顺移一位，没有变化，减去新元素即可\n",
    "                    pre -= (n - c)\n",
    "            res.append(pre + (mid + 1) * s[mid] - (l - mid - 1) * s[mid])\n",
    "            c += 1\n",
    "            res[-1] %= 10 ** 9 + 7\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from heapq import heappush, heappop\n",
    "\n",
    "class Solution:\n",
    "    mod = 1000000007\n",
    "\n",
    "    def numsGame(self, nums: List[int]) -> List[int]:\n",
    "        n = len(nums)\n",
    "        if n == 1:\n",
    "            return [0]\n",
    "        \n",
    "        for i in range(n):\n",
    "            nums[i] -= i\n",
    "        \n",
    "        q0, q1 = [-min(nums[0], nums[1])], [max(nums[0], nums[1])]\n",
    "        sum0, sum1 = -q0[0], q1[0]\n",
    "        ans = [0, int(sum1 - sum0) % self.mod]\n",
    "\n",
    "        for i in range(2, n):\n",
    "            if nums[i] <= -q0[0]:\n",
    "                heappush(q0, -nums[i])\n",
    "                sum0 += nums[i]\n",
    "            else:\n",
    "                heappush(q1, nums[i])\n",
    "                sum1 += nums[i]\n",
    "            \n",
    "            if len(q0) == len(q1) + 2:\n",
    "                u = -heappop(q0)\n",
    "                sum0 -= u\n",
    "                heappush(q1, u)\n",
    "                sum1 += u\n",
    "            elif len(q0) + 1 == len(q1):\n",
    "                u = heappop(q1)\n",
    "                sum1 -= u\n",
    "                heappush(q0, -u)\n",
    "                sum0 += u\n",
    "            \n",
    "            delta = sum1 - sum0 + (-q0[0] if not i & 1 else 0)\n",
    "            ans.append(delta % self.mod)\n",
    "\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        from collections import Counter\n",
    "        num = 0\n",
    "        dct = {}\n",
    "        for ds in demand:\n",
    "            freq = Counter(ds)\n",
    "            for k, v in freq.items():\n",
    "                if k not in dct:\n",
    "                    dct[k] = v\n",
    "                else:\n",
    "                    dct[k] = max(dct[k], v) \n",
    "        return sum(dct.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        mp = Counter()\n",
    "        for s in demand:\n",
    "            c = Counter(s)\n",
    "            for k, v in c.items():\n",
    "                if k not in mp:\n",
    "                    mp[k] = v\n",
    "                else:\n",
    "                    mp[k] = max(v, mp[k])\n",
    "        return sum(mp.values())\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        cnt = defaultdict(int)\n",
    "        for d in demand:\n",
    "            c = Counter(d)\n",
    "            for k in c:\n",
    "                cnt[k]=max(cnt[k],c[k])\n",
    "        return sum(cnt.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        alphabet = defaultdict(int)\n",
    "        for s in demand:\n",
    "            t = defaultdict(int)\n",
    "            for ch in s:\n",
    "                t[ch] += 1\n",
    "                alphabet[ch] = max(alphabet[ch], t[ch])\n",
    "        return sum(alphabet.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        res = defaultdict(int)\n",
    "        for row in demand:\n",
    "            for ch, c in Counter(row).items():\n",
    "                res[ch] = max(res[ch], c)\n",
    "        return sum(res.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        # print(collections.Counter(a))\n",
    "        tmp = dict()\n",
    "        for i in demand:\n",
    "            tmp_dict = dict(collections.Counter(i))\n",
    "            for i in tmp_dict:\n",
    "                if i in tmp and tmp_dict[i] >= tmp[i]:\n",
    "                    tmp[i] = tmp_dict[i]\n",
    "                elif i in tmp and tmp_dict[i] <= tmp[i]:\n",
    "                    # 如果当前没大于之前的次数，则忽略\n",
    "                    continue\n",
    "                else:\n",
    "                    tmp[i] = tmp_dict[i]\n",
    "            \n",
    "        return sum(tmp.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        d=collections.Counter(demand[0])\n",
    "        for i in range(1,len(demand)):\n",
    "            s=d|collections.Counter(demand[i])\n",
    "            d=s\n",
    "        return sum(d.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "\n",
    "        res = defaultdict(int)\n",
    "        for row in demand:\n",
    "            for ch, c in Counter(row).items():\n",
    "                res[ch] = max(res[ch], c)\n",
    "        return sum(res.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        xf = [0 for _ in range(26)]\n",
    "        for s in demand:\n",
    "            cur = [0 for _ in range(26)]\n",
    "            for c in s:\n",
    "                ID = ord(c) - ord('a')\n",
    "                cur[ID] += 1\n",
    "            for x in range(26):\n",
    "                xf[x] = max(xf[x], cur[x])\n",
    "        res = sum(xf)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        ans = Counter()\n",
    "        for d in demand:\n",
    "            temp = Counter(d)\n",
    "            for key in temp.keys():\n",
    "                ans[key] = ans[key] if ans[key] >= temp[key] else temp[key]\n",
    "        return sum(ans.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def minNumBooths(self, demand: List[str]) -> int:\n",
    "    mapping = defaultdict(int)\n",
    "    for day in demand:\n",
    "      for k, v in Counter(day).items():\n",
    "        mapping[k] = max(mapping[k], v)\n",
    "    return sum(mapping.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        d0 = {}\n",
    "        for i in range(len(demand)):\n",
    "            d = {}\n",
    "            for c in demand[i]:\n",
    "                if not c in d:\n",
    "                    d[c] = 1\n",
    "                else:\n",
    "                    d[c] += 1\n",
    "            for c in d:\n",
    "                count = d[c]\n",
    "                if not c in d0 or d0[c] < count:\n",
    "                    d0[c] = count\n",
    "        return sum(d0.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_,map(Counter,demand)).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        xf = [0 for _ in range(26)]\n",
    "        for s in demand:\n",
    "            cur = [0 for _ in range(26)]\n",
    "            for c in s:\n",
    "                ID = ord(c) - ord('a')\n",
    "                cur[ID] += 1\n",
    "            for x in range(26):\n",
    "                xf[x] = max(xf[x], cur[x])\n",
    "        \n",
    "        res = sum(xf)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        from collections import Counter\n",
    "        num = 0\n",
    "        dct = {}\n",
    "        for ds in demand:\n",
    "            freq = Counter(ds)\n",
    "            for k, v in freq.items():\n",
    "                if k not in dct:\n",
    "                    dct[k] = v\n",
    "                else:\n",
    "                    dct[k] = max(dct[k], v) \n",
    "        return sum(dct.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        c=Counter(demand[0])\n",
    "        for i in demand:\n",
    "            c=Counter(i)|c\n",
    "        return sum(c.values())\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        p = dict([])\n",
    "        for i in demand:\n",
    "            day = Counter(i)\n",
    "            for d in day:\n",
    "                if d not in p:\n",
    "                    p[d] = day[d]\n",
    "                else:\n",
    "                    p[d] = max(p[d], day[d])\n",
    "        return sum(p.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "\n",
    "        res = []\n",
    "\n",
    "        for i in demand:\n",
    "            c = Counter(i)\n",
    "            res.append(c)\n",
    "\n",
    "        d = {}\n",
    "\n",
    "        for j in res:\n",
    "            for k in j:\n",
    "                if k not in d:\n",
    "                    d[k] = j[k]\n",
    "                elif j[k] > d[k]:\n",
    "                    d[k] = j[k]\n",
    "\n",
    "        return sum(d.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        cnt = dict()\n",
    "        for item in demand:\n",
    "            counter = Counter(item)\n",
    "            for k,v in counter.items():\n",
    "                if k not in cnt or cnt[k]<v:\n",
    "                    cnt[k]=v\n",
    "        return sum(cnt.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        char = \"qwertyuiopasdfghjklzxcvbnm\"\n",
    "        limit = {char[i]: 0 for i in range(len(char))}\n",
    "        for d in demand:\n",
    "            count = {char[i]: 0 for i in range(len(char))}\n",
    "            for j in d:\n",
    "                count[j] += 1\n",
    "            for k in d:\n",
    "                if limit[k] < count[k]:\n",
    "                    limit[k] = count[k]\n",
    "\n",
    "        return sum(limit.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        # 遍历每个字符串 得到字母出现次数 要是大于之前的最大值就更新\n",
    "        use = []\n",
    "        ans = []\n",
    "        for i in range(27):\n",
    "            use.append(0)\n",
    "            ans.append(0)\n",
    "\n",
    "        for i in demand:\n",
    "            for j in range(27):\n",
    "                use[j] = 0\n",
    "            # 每遍历一次字符串就清空一次use数组   \n",
    "            for j in i:\n",
    "                use[ord(j)-ord('a')] += 1\n",
    "            \n",
    "            for j in range(27):\n",
    "                if use[j] > ans[j]:ans[j] = use[j]\n",
    "\n",
    "        return sum(ans)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "\n",
    "        res = []\n",
    "\n",
    "        for i in demand:\n",
    "            c = Counter(i)\n",
    "            res.append(c)\n",
    "\n",
    "        d = {}\n",
    "\n",
    "        for j in res:\n",
    "            for k in j:\n",
    "                if k not in d:\n",
    "                    d[k] = j[k]\n",
    "                elif j[k] > d[k]:\n",
    "                    d[k] = j[k]\n",
    "\n",
    "        return sum(d.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        booths = [0] * 26\n",
    "        for d in demand:\n",
    "            m = Counter(d)\n",
    "            for key, value in m.items():\n",
    "                index = ord(key) - ord('a')\n",
    "                booths[index] = max(booths[index], value)\n",
    "        return sum(booths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        l=[0]*26\n",
    "        for i in demand:\n",
    "            cnt=Counter(i)\n",
    "            for j in cnt:\n",
    "                if l[ord(j)-ord('a')]<cnt[j]:\n",
    "                    l[ord(j)-ord('a')]=cnt[j]\n",
    "        return sum(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        booths = [0] * 26\n",
    "        for d in demand:\n",
    "            m = defaultdict(int)\n",
    "            for s in d:\n",
    "                m[s] += 1\n",
    "            for key, value in m.items():\n",
    "                index = ord(key) - ord('a')\n",
    "                booths[index] = max(booths[index], value)\n",
    "        return sum(booths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        res = Counter()\n",
    "        for d in demand:\n",
    "            tmp = Counter(d)\n",
    "            for key in tmp.keys():\n",
    "                res[key] = res[key] if res[key] >= tmp[key] else tmp[key]\n",
    "        return sum(res.values())\n",
    "                     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        hax = {}\n",
    "        for x in demand:\n",
    "            z = 1\n",
    "            for y in x:\n",
    "                if y not in hax:\n",
    "                    hax[y] = 1\n",
    "                else:\n",
    "                    hax[y] = max(hax[y], x.count(y)) \n",
    "        return sum(hax.values())\n",
    "                     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        zt = {}\n",
    "        for i in range(len(demand)):\n",
    "            cnt = {}\n",
    "            for c in demand[i]:\n",
    "                if c in cnt.keys():\n",
    "                    cnt[c]+=1\n",
    "                else:\n",
    "                    cnt[c]=1\n",
    "            for x in cnt.keys():\n",
    "                if x in zt.keys():\n",
    "                    zt[x] = max(zt[x], cnt[x])\n",
    "                else:\n",
    "                    zt[x]=cnt[x]\n",
    "\n",
    "        s=sum(zt.values())\n",
    "        return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        res = Counter()\n",
    "        for d in demand:\n",
    "            tmp = Counter(d)\n",
    "            for key in tmp.keys():\n",
    "                res[key] = res[key] if res[key] >= tmp[key] else tmp[key]\n",
    "        return sum(res.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        ans = [0] * 26\n",
    "        for d in demand:\n",
    "            cnt = Counter(d)\n",
    "            for k, v in cnt.items():\n",
    "                i = ord(k) - ord('a')\n",
    "                ans[i] = max(ans[i], v)\n",
    "        return sum(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        booths = [0] * 26\n",
    "        for d in demand:\n",
    "            m = defaultdict(int)\n",
    "            for s in d:\n",
    "                m[s] += 1\n",
    "            for key, value in m.items():\n",
    "                index = ord(key) - ord('a')\n",
    "                booths[index] = max(booths[index], value)\n",
    "        return sum(booths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())\n",
    "        \n",
    "\n",
    "        \n",
    "                \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        demandDict = {}\n",
    "        for data in demand:\n",
    "            thisDict = {}\n",
    "            for b in data:\n",
    "                if b in thisDict:\n",
    "                    thisDict[b]+=1\n",
    "                else:\n",
    "                    thisDict[b] = 1\n",
    "            for this in thisDict:\n",
    "                if (this in demandDict and demandDict[this] < thisDict[this]) or this not in demandDict:\n",
    "                    demandDict[this] = thisDict[this]\n",
    "        \n",
    "        return sum(demandDict[key] for key in demandDict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        res = Counter()\n",
    "        for d in demand:\n",
    "            tmp = Counter(d)\n",
    "            res = res | tmp\n",
    "        return sum(res.values())\n",
    "                     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        dic={}\n",
    "        res=0\n",
    "        for day in demand:\n",
    "            for ch in day:\n",
    "                if ch in dic:\n",
    "                    # ch-某个展台，如果这个展台在 dic里，那就看今天这个展台需要的数量，和 dic里已有的数量，取最大值进行更新\n",
    "                    dic[ch]=max(day.count(ch),dic[ch])\n",
    "                else:\n",
    "                    # 如果是新添加的展台，就按照当天的需求数量进行增加\n",
    "                    dic[ch]=day.count(ch)\n",
    "        # 所有的展台数量\n",
    "        nums=[value for value in dic.values()]\n",
    "        return sum(nums)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        d = dict()\n",
    "        for str in demand:\n",
    "            for ch in str:\n",
    "                if ch not in d:\n",
    "                    d[ch] = str.count(ch)\n",
    "                else:\n",
    "                    d[ch] = max(d[ch], str.count(ch))\n",
    "        return sum(d.values())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        demand = [Counter(i) for i in demand]\n",
    "        c = Counter()\n",
    "        for i in demand:\n",
    "            for j in i:\n",
    "                c[j] = max(c[j], i[j])\n",
    "        return sum(i for i in c.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# ### my：数组+遍历\n",
    "# class Solution:\n",
    "#     def minNumBooths(self, demand: List[str]) -> int:\n",
    "#         pre=[0]*26\n",
    "#         for d in demand:\n",
    "#             cur=[0]*26\n",
    "#             for ch in d:\n",
    "#                 cur[ord(ch)-ord(\"a\")]+=1\n",
    "#             for i in range(26):\n",
    "#                 cur[i]=max(cur[i],pre[i])\n",
    "#             pre=cur\n",
    "#         return sum(pre)\n",
    "\n",
    "### 灵茶山：\n",
    "class Solution:\n",
    "\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "\n",
    "        return sum(reduce(or_, map(Counter, demand)).values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        count = {}\n",
    "        for i in demand:\n",
    "            t = Counter(i)\n",
    "            for k, v in t.items():\n",
    "                if k not in count.keys():\n",
    "                    count[k] = v\n",
    "                else:\n",
    "                    if count[k] < v:\n",
    "                        count[k] = v\n",
    "        return sum(count.values())\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        counter = set(''.join(demand))\n",
    "        dc = {}\n",
    "        for words in demand:\n",
    "            char_counter = Counter(words).items()\n",
    "            for key, value in char_counter:\n",
    "                if value != 1:\n",
    "                    if value > dc.get(key, 0):\n",
    "                        dc[key] = value\n",
    "\n",
    "        flag = sum(dc.values(), -len(dc))\n",
    "       \n",
    "        return len(counter) + flag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        counter = set(''.join(demand))\n",
    "        dc = {}\n",
    "        for words in demand:\n",
    "            char_counter = Counter(words).items()\n",
    "            for key, value in char_counter:\n",
    "                if value != 1:\n",
    "                    if value > dc.get(key, 0):\n",
    "                        dc[key] = value\n",
    "\n",
    "        flag = sum(dc.values()) - len(dc)\n",
    "       \n",
    "        return len(counter) + flag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "\n",
    "        res = []\n",
    "\n",
    "        for i in demand:\n",
    "            c = Counter(i)\n",
    "            res.append(c)\n",
    "\n",
    "        d = {}\n",
    "\n",
    "        for j in res:\n",
    "            for k in j:\n",
    "                if k not in d:\n",
    "                    d[k] = j[k]\n",
    "                elif j[k] > d[k]:\n",
    "                    d[k] = j[k]\n",
    "\n",
    "        return sum(d.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minNumBooths(self, demand: List[str]) -> int:\n",
    "        return sum(max(x.count(c) for x in demand) for c in ascii_lowercase)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "\n",
    "        if root is None: return 0\n",
    "\n",
    "        def inner(node, ssum):\n",
    "            if node is None: return 0\n",
    "            res = 0\n",
    "            if node.val == ssum:\n",
    "                res += 1\n",
    "            res += inner(node.left, ssum - node.val)\n",
    "            res += inner(node.right, ssum - node.val)\n",
    "            return res\n",
    "        \n",
    "        res = inner(root, targetSum)\n",
    "        res += self.pathSum(root.left, targetSum)\n",
    "        res += self.pathSum(root.right, targetSum)\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        \"\"\"\n",
    "        解题思路：递归+穷举，我们遍历每一个节点，计算这个节点向下延申的长度等于targetSum的路径有多少条\n",
    "        \"\"\"\n",
    "        # 函数是为了递归计算路径\n",
    "        def get_sum(root: TreeNode, targetSum: int) -> int:\n",
    "            if not root:\n",
    "                return 0\n",
    "            cur_res = 0\n",
    "            if targetSum == root.val:\n",
    "                cur_res += 1\n",
    "            cur_res += get_sum(root.left, targetSum-root.val)\n",
    "            cur_res += get_sum(root.right, targetSum-root.val)\n",
    "            return cur_res\n",
    "\n",
    "        # special case\n",
    "        if not root:\n",
    "            return 0\n",
    "        # 递归函数入口，用前序遍历访问每一个节点，注意这里的第2个参数，这个位置是遍历，不是递归\n",
    "        res = get_sum(root, targetSum)\n",
    "        res += self.pathSum(root.left, targetSum)\n",
    "        res += self.pathSum(root.right, targetSum)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    ans = 0\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        self.ans = 0\n",
    "        pre_sum_map = defaultdict(int)\n",
    "        pre_sum_map[0] = 1\n",
    "\n",
    "        def helper(node: TreeNode, prev: int):\n",
    "            if not node:\n",
    "                return\n",
    "            prev += node.val\n",
    "            self.ans += pre_sum_map.get(prev - targetSum, 0)\n",
    "            pre_sum_map[prev] += 1\n",
    "            helper(node.left, prev)\n",
    "            helper(node.right, prev)\n",
    "            pre_sum_map[prev] -= 1\n",
    "            prev -= node.val\n",
    "        helper(root, 0)\n",
    "        return self.ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "\n",
    "        # top-down or bottom-up should both OK\n",
    "        # prefix sum idea + dfs\n",
    "\n",
    "        # ret = 0\n",
    "        # def dfs(n, d):\n",
    "        #     if not n:\n",
    "        #         return\n",
    "\n",
    "        #     # print({k:v for k, v in d.items() if v != 0})\n",
    "\n",
    "        #     t = targetSum - n.val\n",
    "        #     nonlocal ret\n",
    "        #     # if d[t] != 0:\n",
    "        #     #     print(f'{n.val} {t} {d[t]}')   \n",
    "        #     ret += d[t]\n",
    "\n",
    "        #     # above check is the path start is from root to current parent and end is current\n",
    "        #     # so if t==0 then only current is satisfy the condition\n",
    "        #     # so stand alone check t == 0 make sense\n",
    "        #     if t == 0:\n",
    "        #         ret += 1\n",
    "\n",
    "        #     nd = defaultdict(int)\n",
    "        #     nd[n.val] = 1\n",
    "        #     for k, v in d.items():\n",
    "        #         nd[k+n.val] += v\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] += v\n",
    "\n",
    "        #     dfs(n.left, nd)\n",
    "        #     dfs(n.right, nd)\n",
    "\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] -= v\n",
    "        \n",
    "        # d = defaultdict(int)\n",
    "        # # d[0] = 1\n",
    "        # dfs(root, d)\n",
    "\n",
    "        # return ret\n",
    "\n",
    "        # from ans, above solution doesn't use prefix at all\n",
    "        # d should record the all path sum from root to any ancestor of the cur node (prefix)\n",
    "        # and from root to cur node sum - targetVal if in d, then it means the ancester to cur node equal targetVal\n",
    "        # wholeSum - targetVal = prefixSum\n",
    "        # targetVal = wholeSum - prefixSum\n",
    "        # targetVal = sum(ancester to cur node)\n",
    "\n",
    "        ret = 0\n",
    "        def dfs(n, d, s):\n",
    "            if not n:\n",
    "                return\n",
    "\n",
    "            print({k:v for k, v in d.items() if v != 0})\n",
    "            s += n.val\n",
    "            t = s - targetSum\n",
    "            nonlocal ret\n",
    "            if d[t] != 0:\n",
    "                print(f'{s} {n.val} {t} {d[t]}')   \n",
    "            ret += d[t]\n",
    "\n",
    "            d[s] += 1\n",
    "            \n",
    "            dfs(n.left, d, s)\n",
    "            dfs(n.right, d, s)\n",
    "\n",
    "            d[s] -= 1\n",
    "        \n",
    "        d = defaultdict(int)\n",
    "\n",
    "        # key is put prefix sum(0)\n",
    "        # thus include the situation from root to leaf\n",
    "        # this solution slower than previous unexpected\n",
    "        d[0] = 1\n",
    "        dfs(root, d, 0)\n",
    "\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "\n",
    "        # top-down or bottom-up should both OK\n",
    "        # prefix sum idea + dfs\n",
    "\n",
    "        # ret = 0\n",
    "        # def dfs(n, d):\n",
    "        #     if not n:\n",
    "        #         return\n",
    "\n",
    "        #     # print({k:v for k, v in d.items() if v != 0})\n",
    "\n",
    "        #     t = targetSum - n.val\n",
    "        #     nonlocal ret\n",
    "        #     # if d[t] != 0:\n",
    "        #     #     print(f'{n.val} {t} {d[t]}')   \n",
    "        #     ret += d[t]\n",
    "\n",
    "        #     # above check is the path start is from root to current parent and end is current\n",
    "        #     # so if t==0 then only current is satisfy the condition\n",
    "        #     # so stand alone check t == 0 make sense\n",
    "        #     if t == 0:\n",
    "        #         ret += 1\n",
    "\n",
    "        #     nd = defaultdict(int)\n",
    "        #     nd[n.val] = 1\n",
    "        #     for k, v in d.items():\n",
    "        #         nd[k+n.val] += v\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] += v\n",
    "\n",
    "        #     dfs(n.left, nd)\n",
    "        #     dfs(n.right, nd)\n",
    "\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] -= v\n",
    "        \n",
    "        # d = defaultdict(int)\n",
    "        # # d[0] = 1\n",
    "        # dfs(root, d)\n",
    "\n",
    "        # return ret\n",
    "\n",
    "        # from ans, above solution doesn't use prefix at all\n",
    "        # d should record the all path sum from root to any ancestor of the cur node (prefix)\n",
    "        # and from root to cur node sum - targetVal if in d, then it means the ancester to cur node equal targetVal\n",
    "        # wholeSum - targetVal = prefixSum\n",
    "        # targetVal = wholeSum - prefixSum\n",
    "        # targetVal = sum(ancester to cur node)\n",
    "\n",
    "        ret = 0\n",
    "        def dfs(n, d, s):\n",
    "            if not n:\n",
    "                return\n",
    "\n",
    "            print({k:v for k, v in d.items() if v != 0})\n",
    "            s += n.val\n",
    "            t = s - targetSum\n",
    "            nonlocal ret\n",
    "            if d[t] != 0:\n",
    "                print(f'{s} {n.val} {t} {d[t]}')   \n",
    "            ret += d[t]\n",
    "\n",
    "            d[s] += 1\n",
    "            \n",
    "            dfs(n.left, d, s)\n",
    "            dfs(n.right, d, s)\n",
    "\n",
    "            d[s] -= 1\n",
    "        \n",
    "        d = defaultdict(int)\n",
    "\n",
    "        # key is put prefix sum(0)\n",
    "        # thus include the situation from root to leaf\n",
    "        # this solution slower than previous unexpected\n",
    "        d[0] = 1\n",
    "        dfs(root, d, 0)\n",
    "\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        self.res = 0\n",
    "        def dfs(node,nums):\n",
    "            if not node: return\n",
    "            nums.append(node.val)\n",
    "            for i in range(len(nums)):\n",
    "                if sum(nums[i:])==targetSum:self.res+=1\n",
    "            dfs(node.left,nums[:])\n",
    "            dfs(node.right,nums[:])\n",
    "        dfs(root,[])\n",
    "        return self.res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:\n",
    "        if root is None:\n",
    "            return 0\n",
    "        return self.path_sum(root, targetSum, [])\n",
    "\n",
    "    def path_sum(\n",
    "        self,\n",
    "        root: Optional[TreeNode],\n",
    "        targetSum: int,\n",
    "        r_sum: List[int],\n",
    "    ) -> int:\n",
    "        sum_path = root.val + (r_sum[-1] if len(r_sum) > 0 else 0)\n",
    "        num_paths = 1 if sum_path == targetSum else 0\n",
    "        for r in r_sum:\n",
    "            if sum_path - r == targetSum:\n",
    "                num_paths += 1\n",
    "        if root.left is not None:\n",
    "            num_paths += self.path_sum(\n",
    "                root.left,\n",
    "                targetSum,\n",
    "                r_sum + [sum_path],\n",
    "            )\n",
    "        if root.right is not None:\n",
    "            num_paths += self.path_sum(\n",
    "                root.right,\n",
    "                targetSum,\n",
    "                r_sum + [sum_path],\n",
    "            )\n",
    "        return num_paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "\n",
    "    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:\n",
    "        self.getPath(root, targetSum)\n",
    "        return self.res\n",
    "\n",
    "    def getPath(self, node, targetSum):\n",
    "        if not node:\n",
    "            return []\n",
    "        tmp = [[node.val]]\n",
    "        if node.val == targetSum:\n",
    "            self.res += 1\n",
    "\n",
    "        if node.left:\n",
    "            for p in self.getPath(node.left, targetSum):\n",
    "                new_path = [node.val] + p\n",
    "                if sum(new_path) == targetSum:\n",
    "                    self.res += 1\n",
    "                tmp.append(new_path)\n",
    "                \n",
    "        if node.right:\n",
    "            for p in self.getPath(node.right, targetSum):\n",
    "                new_path = [node.val] + p\n",
    "                if sum(new_path) == targetSum:\n",
    "                    self.res += 1\n",
    "                tmp.append(new_path)\n",
    "        \n",
    "        return tmp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.res = 0\n",
    "\n",
    "    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:\n",
    "        self.getPath(root, targetSum)\n",
    "        return self.res\n",
    "\n",
    "    def getPath(self, node, targetSum):\n",
    "        if not node:\n",
    "            return []\n",
    "        tmp = [[node.val]]\n",
    "        if node.val == targetSum:\n",
    "            self.res += 1\n",
    "\n",
    "        if node.left:\n",
    "            for p in self.getPath(node.left, targetSum):\n",
    "                new_path = [node.val] + p\n",
    "                if sum(new_path) == targetSum:\n",
    "                    self.res += 1\n",
    "                tmp.append(new_path)\n",
    "                \n",
    "        if node.right:\n",
    "            for p in self.getPath(node.right, targetSum):\n",
    "                new_path = [node.val] + p\n",
    "                if sum(new_path) == targetSum:\n",
    "                    self.res += 1\n",
    "                tmp.append(new_path)\n",
    "        \n",
    "        return tmp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        if root == None:\n",
    "            return 0\n",
    "        sum_dict = defaultdict(int)\n",
    "        father_dict = defaultdict(list)\n",
    "\n",
    "        def dfs(node,sum_cur,node_pre):\n",
    "            sum_cur += node.val\n",
    "            sum_dict[node]=sum_cur\n",
    "            if node_pre != None:\n",
    "                father_dict[node] = father_dict[node_pre]+[node_pre]\n",
    "            if node.left:\n",
    "                dfs(node.left,sum_cur,node)\n",
    "            if node.right:\n",
    "                dfs(node.right,sum_cur,node)\n",
    "        \n",
    "        dfs(root,0,None)\n",
    "        res = [0]\n",
    "        def dfs_view(node):\n",
    "            if sum_dict[node] == targetSum:\n",
    "                    res[0]+=1\n",
    "            for i in father_dict[node]:\n",
    "                if sum_dict[node] - sum_dict[i] == targetSum:\n",
    "                    res[0]+=1\n",
    "\n",
    "            if node.left:\n",
    "                dfs_view(node.left)\n",
    "            if node.right:\n",
    "                dfs_view(node.right)\n",
    "        dfs_view(root)\n",
    "        return res[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "from collections import Counter\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int, pre=0, presum=None) -> int:\n",
    "        if root is None:\n",
    "            return 0\n",
    "        \n",
    "        if presum is None:\n",
    "            presum = Counter()\n",
    "            presum[pre] += 1\n",
    "        \n",
    "        pre += root.val\n",
    "        ans = presum[pre - targetSum]\n",
    "        presum[pre] += 1\n",
    "\n",
    "        ans += self.pathSum(root.left, targetSum, pre, presum.copy())\n",
    "        ans += self.pathSum(root.right, targetSum, pre, presum)\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "        self.count=0\n",
    "        def recur(cur,sums):\n",
    "            if not cur:return \n",
    "           \n",
    "            sums.append(sums[-1]+cur.val)\n",
    "            s1=sums[:]\n",
    "            s2=s1[:]\n",
    "            n=len(sums)\n",
    "            for  i in range(n-1):\n",
    "                if sums[-1]-sums[i]==targetSum:\n",
    "                   \n",
    "                    self.count+=1\n",
    "            recur(cur.left,s1)\n",
    "            recur(cur.right,s2)\n",
    "        \n",
    "        recur(root,[0])\n",
    "        return self.count\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "\n",
    "        q = deque([root])\n",
    "        res = 0 if root.val!=targetSum else 1\n",
    "        dic = {}\n",
    "        dic[root] = [root.val]\n",
    "        while q:\n",
    "            v = q.popleft()\n",
    "            vsum = dic[v]\n",
    "            if v.left:\n",
    "                q.append(v.left)\n",
    "                lsum = []\n",
    "                lval = v.left.val\n",
    "                for i in range(len(vsum)):\n",
    "                    a = vsum[i] + lval\n",
    "                    lsum.append(a)\n",
    "                    if a==targetSum:\n",
    "                        res+=1\n",
    "                lsum.append(lval)\n",
    "                if lval==targetSum:\n",
    "                    res+=1\n",
    "                dic[v.left] = lsum\n",
    "            if v.right:\n",
    "                q.append(v.right)\n",
    "                rsum = []\n",
    "                rval = v.right.val\n",
    "                for i in range(len(vsum)):\n",
    "                    b = vsum[i] + rval\n",
    "                    rsum.append(b)\n",
    "                    if b==targetSum:\n",
    "                        res+=1\n",
    "                rsum.append(rval)\n",
    "                if rval==targetSum:\n",
    "                    res+=1\n",
    "                dic[v.right] = rsum\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        if not root:\n",
    "            return 0\n",
    "\n",
    "        q = deque([root])\n",
    "        res = 0 if root.val!=targetSum else 1\n",
    "        dic = {}\n",
    "        dic[root] = [root.val]\n",
    "        while q:\n",
    "            v = q.popleft()\n",
    "            vsum = dic[v]\n",
    "            if v.left:\n",
    "                q.append(v.left)\n",
    "                lsum = []\n",
    "                lval = v.left.val\n",
    "                for i in range(len(vsum)):\n",
    "                    a = vsum[i] + lval\n",
    "                    lsum.append(a)\n",
    "                    if a==targetSum:\n",
    "                        res+=1\n",
    "                lsum.append(lval)\n",
    "                if lval==targetSum:\n",
    "                    res+=1\n",
    "                dic[v.left] = lsum\n",
    "            if v.right:\n",
    "                q.append(v.right)\n",
    "                rsum = []\n",
    "                rval = v.right.val\n",
    "                for i in range(len(vsum)):\n",
    "                    b = vsum[i] + rval\n",
    "                    rsum.append(b)\n",
    "                    if b==targetSum:\n",
    "                        res+=1\n",
    "                rsum.append(rval)\n",
    "                if rval==targetSum:\n",
    "                    res+=1\n",
    "                dic[v.right] = rsum\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        self.count = 0\n",
    "\n",
    "        if root is None:\n",
    "            return self.count\n",
    "\n",
    "        def dfs(node: TreeNode, sum_lst: List[int]) -> None:\n",
    "            if node is None:\n",
    "                return\n",
    "\n",
    "            sum_lst = [node.val + num for num in sum_lst]\n",
    "            sum_lst.append(node.val)\n",
    "\n",
    "            self.count += sum_lst.count(targetSum)\n",
    "\n",
    "            dfs(node.left, sum_lst)\n",
    "            dfs(node.right, sum_lst)\n",
    "\n",
    "        dfs(root, [])\n",
    "\n",
    "        return self.count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "        def dfs(node,sumlist):\n",
    "            res = 0\n",
    "            if not node:\n",
    "                return 0\n",
    "            sumlist = [num + node.val for num in sumlist]\n",
    "            sumlist.append(node.val)\n",
    "\n",
    "            count = 0\n",
    "            for num in sumlist:\n",
    "                if num == targetSum:\n",
    "                    count += 1\n",
    "            return count + dfs(node.left,sumlist) + dfs(node.right,sumlist)\n",
    "        return dfs(root,[])\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n=len(edges)  \n",
    "        res=[]    \n",
    "        for i in range(n):# 丢掉第n个\n",
    "            connect=[[] for _ in range(n)]\n",
    "            for j,edge in enumerate(edges):\n",
    "                if j==i:\n",
    "                    continue\n",
    "                connect[edge[0]-1].append(edge[1]-1)\n",
    "                connect[edge[1]-1].append(edge[0]-1)\n",
    "            seen=[False]*n\n",
    "            q=collections.deque([0])\n",
    "            while q:\n",
    "                cur= q.popleft()\n",
    "                seen[cur]=True\n",
    "                for node in connect[cur]:\n",
    "                    if seen[node]==False and not(node in q):\n",
    "                        q.append(node)\n",
    "            if sum(seen)==n:\n",
    "                res=edges[i]\n",
    "        return res\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        used = [0] * n\n",
    "\n",
    "        ans = []\n",
    "        def backtrack(path, used):\n",
    "            if sum(used)==n:\n",
    "                ans.append(path+[])\n",
    "                return\n",
    "            \n",
    "            for i in range(0, n):\n",
    "                if used[i]:\n",
    "                    continue\n",
    "                \n",
    "                if i>0 and nums[i]==nums[i-1] and used[i-1]==0:\n",
    "                    continue\n",
    "\n",
    "                used[i] = 1\n",
    "                path.append(nums[i])\n",
    "                backtrack(path, used)\n",
    "                used[i] = 0\n",
    "                path.pop()\n",
    "        \n",
    "        backtrack([], used)\n",
    "        return ans\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        # 数组、哈希表、前缀和\n",
    "        # 0和1的数量相同，等价于1的数量减去0的数量等于0\n",
    "        # 我们可将数组中0视作-1，则原问题转换为求最长的连续子数组，其元素和为0\n",
    "        maxlength = 0\n",
    "        presum = 0\n",
    "        # 定义哈希表，键值对为 前缀和：首次出现该前缀和时的索引\n",
    "        # 规定空的前缀和的下标为-1，空前缀和的元素和为0，因此在遍历前在哈希表中存入键值对(0, -1)\n",
    "        dic = {0: -1}\n",
    "        n = len(nums)\n",
    "        for k, v in enumerate(nums):\n",
    "            # 遍历数组，遇到1时，presum加1，遇到0时，presum减1\n",
    "            if v == 1:\n",
    "                presum += 1\n",
    "            else:\n",
    "                presum -= 1\n",
    "            # 关键：如果当前前缀和出现在字典中，说明该前缀和在前面出现过，不断添加n个元素后，前缀和仍为\n",
    "            # 当前前缀和的值，说明中间的这n个元素和为0。\n",
    "            if presum in dic:\n",
    "                # 此时更新最终结果，用当前下标减去第一次出现的下标。即为当前最长连续子数组\n",
    "                # 此时无需更新字典中的下标位置，是因为如果后面再次出现相同的前缀和，仍说明\n",
    "                # 这中间的m个元素和为0。\n",
    "                firstindex = dic[presum]\n",
    "                maxlength = max(maxlength, k - firstindex)\n",
    "            else:\n",
    "                # 若没出现则将当前第一次出现的前缀和添加到字典中。\n",
    "                dic[presum] = k\n",
    "        return maxlength"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        presum = {0:-1}\n",
    "        s = 0\n",
    "        maxlen = 0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] == 0:\n",
    "                s -= 1\n",
    "            else:\n",
    "                s += 1\n",
    "            if s in presum:\n",
    "                presum[s] = min(presum[s],i)\n",
    "            else:\n",
    "                presum[s] = i\n",
    "            if  s-0 in presum:\n",
    "                left = presum[s-0]\n",
    "                maxlen = max(maxlen,i - presum[s-0])\n",
    "                \n",
    "        return maxlen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        maxlength, presum = 0, 0\n",
    "        dic = {0: -1}\n",
    "        for k, v in enumerate(nums):\n",
    "            if v == 1:\n",
    "                presum += 1\n",
    "            else:\n",
    "                presum -= 1\n",
    "            if presum in dic:\n",
    "                firstindex = dic[presum]\n",
    "                maxlength = max(maxlength, k - firstindex)\n",
    "            else:\n",
    "                dic[presum] = k\n",
    "        return maxlength"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        prefix_sum = 0\n",
    "        sum_mapping = {0:-1}\n",
    "        ans = 0\n",
    "        for idx,num in enumerate(nums):\n",
    "            if num==0:\n",
    "                prefix_sum -=1\n",
    "            else:\n",
    "                prefix_sum += 1\n",
    "            if prefix_sum not in sum_mapping:\n",
    "                sum_mapping[prefix_sum] = idx\n",
    "            else:\n",
    "                ans = max(ans,idx-sum_mapping[prefix_sum])\n",
    "        return ans\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        d = {}\n",
    "        rs = 0\n",
    "        tmp_sum = 0\n",
    "        for idx, num in enumerate(nums):  # 0转为-1，这样和为0的时候二者数量是一样的，0多的时候取前一个相同数量0的位置到当前位置即可\n",
    "            if num==0:\n",
    "                tmp_sum += -1\n",
    "            else:\n",
    "                tmp_sum += 1\n",
    "            if tmp_sum in d:\n",
    "                rs = max(rs, idx-d[tmp_sum])\n",
    "            else:\n",
    "                if tmp_sum==0:  # 第一次和为0即第一次数量相等且未记录时，说明从开头到当前数量一样，故0的前一个下标取-1\n",
    "                    rs = max(rs, idx+1)\n",
    "                    d[0] = -1\n",
    "                else:\n",
    "                    d[tmp_sum] = idx\n",
    "        return rs\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        nums = [1 if i==1 else -1  for i in nums]\n",
    "        presum = {0:-1}\n",
    "        p,m = 0,0\n",
    "        for i,n in enumerate(nums):\n",
    "            p += n \n",
    "            if p not in presum:\n",
    "                presum[p] = i\n",
    "            else:\n",
    "                m = max(m,i-presum[p])\n",
    "        return m\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        res = 0\n",
    "        dic = {}\n",
    "        dic[0] = 0\n",
    "\n",
    "        pre_sum = [0] * (len(nums)+1)\n",
    "        for i in range(1, len(nums)+1):\n",
    "            pre_sum[i] = pre_sum[i-1] + (-1 if nums[i-1]==0 else 1)\n",
    "\n",
    "        for i in range(1, len(nums)+1):\n",
    "            if pre_sum[i] in dic:\n",
    "                res = max(res, i - dic.get(pre_sum[i]))\n",
    "            else:\n",
    "                dic[pre_sum[i]] = i\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "\n",
    "        # 边界条件\n",
    "        if len(nums) < 2: return 0\n",
    "\n",
    "        # 累积和\n",
    "        res = 0\n",
    "        sumMap = collections.defaultdict(list)\n",
    "        sumMap[0] = [-1]\n",
    "        acc1, acc0 = 0, 0\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "\n",
    "            if nums[i] == 0:\n",
    "                acc0 += 1\n",
    "            else:\n",
    "                acc1 += 1\n",
    "            \n",
    "            cur_diff = acc0 - acc1\n",
    "            sumMap[cur_diff].append(i)\n",
    "\n",
    "            # 判断是否存在相同的\n",
    "            if cur_diff in sumMap:\n",
    "                res = max(res, i - sumMap[cur_diff][0])\n",
    "            \n",
    "\n",
    "        # print(sum0)\n",
    "        # print(sum1)\n",
    "\n",
    "        # 遍历\n",
    "        \n",
    "        return res\n",
    "\n",
    "\n",
    "    def findMaxLength2(self, nums: List[int]) -> int:\n",
    "\n",
    "        # 边界条件\n",
    "        if len(nums) < 2: return 0\n",
    "\n",
    "        # 累积和\n",
    "        sum1, sum0 = [0]*(len(nums) + 1), [0]*(len(nums) + 1)\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] == 0:\n",
    "                sum0[i+1] = sum0[i]+1\n",
    "                sum1[i+1] = sum1[i]\n",
    "\n",
    "            else:\n",
    "                sum0[i+1] = sum0[i]\n",
    "                sum1[i+1] = sum1[i] + 1\n",
    "\n",
    "        # print(sum0)\n",
    "        # print(sum1)\n",
    "\n",
    "        # 遍历\n",
    "        res = 0\n",
    "        for i in range(1, len(sum0)):\n",
    "            for j in range(0, i):\n",
    "\n",
    "                if sum0[i] - sum0[j] == sum1[i] - sum1[j]:\n",
    "                    res = max(res, i - j)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        for i in range(len(nums)):\n",
    "            nums[i] = nums[i] - 0.5\n",
    "\n",
    "        sums = 0\n",
    "        memo = {0:-1}\n",
    "        max_len = 0\n",
    "        for i in range(len(nums)):\n",
    "            sums += nums[i]\n",
    "            if sums in memo:\n",
    "                max_len = max(max_len, i-memo[sums])\n",
    "            else:\n",
    "                memo[sums] = i\n",
    "\n",
    "        return max_len\n",
    "                \n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        if len(nums) == 2 and sum(nums) == 1: return 2\n",
    "        dic = defaultdict(list)\n",
    "        dic[0].append(0)\n",
    "        tot = 0\n",
    "        for i in range(1, len(nums)+1):\n",
    "            if nums[i-1] == 0:\n",
    "                tot += -1\n",
    "            else:\n",
    "                tot += 1\n",
    "            dic[tot].append(i)\n",
    "        \n",
    "        res = 0\n",
    "        # print(dic)\n",
    "        for k, v in dic.items():\n",
    "            if len(v)>1:\n",
    "                res = max(res, v[-1]-v[0])\n",
    "      \n",
    "         \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        for i in range(len(nums)):\n",
    "            nums[i] = nums[i] - 0.5\n",
    "\n",
    "        sums = 0\n",
    "        memo = {0:-1}\n",
    "        max_len = 0\n",
    "        for i in range(len(nums)):\n",
    "            sums += nums[i]\n",
    "            if sums in memo:\n",
    "                memo[sums] = min(memo[sums], i)\n",
    "                max_len = max(max_len, i-memo[sums])\n",
    "            else:\n",
    "                memo[sums] = i\n",
    "\n",
    "        return max_len\n",
    "                \n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "\n",
    "\n",
    "        nums = [x if x==1 else -1 for x in nums]\n",
    "\n",
    "        prefix_sum = []\n",
    "        tmp=0\n",
    "        for x in nums:\n",
    "            tmp +=x\n",
    "            prefix_sum.append(tmp)\n",
    "        print(nums)\n",
    "        print(prefix_sum)\n",
    "        prefix_dic = {0:-1}\n",
    "        res=0\n",
    "        for i,x in enumerate(prefix_sum):\n",
    "            if x in prefix_dic:\n",
    "                res = max(res,i-prefix_dic[x])\n",
    "            else:\n",
    "                prefix_dic[x]=i \n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        summary = 0\n",
    "        dic = defaultdict(list)\n",
    "        dic[0].append(-1)\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] == 1:\n",
    "                summary = summary+1\n",
    "            else:\n",
    "                summary = summary-1\n",
    "            dic[summary].append(i)\n",
    "        ans = 0\n",
    "        for value in dic.values():\n",
    "            ans = max(ans,max(value)-min(value))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        sum_pre = {}\n",
    "        pre, ans = 0, 0\n",
    "        for i, num in enumerate(nums):\n",
    "            pre += num * 2 - 1\n",
    "            if pre in sum_pre.keys():\n",
    "                ans = max(ans, i - min(sum_pre[pre]))\n",
    "            if pre == 0:\n",
    "                ans = max(ans, i + 1)\n",
    "            if pre in sum_pre.keys():\n",
    "                sum_pre[pre].append(i)\n",
    "            else:\n",
    "                sum_pre[pre] = [i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        # if len(nums)==1:\n",
    "        #     return 0\n",
    "\n",
    "        # csum = [0]+[nums[0]]\n",
    "        # len_ = len(nums)\n",
    "        # for i, v in enumerate(nums):\n",
    "        #     if i >0:\n",
    "        #         csum.append(csum[-1]+v)\n",
    "\n",
    "        # max_ = 0\n",
    "        # for i, v in enumerate(nums):\n",
    "        #     j = i+1\n",
    "        #     while (j-i+1)%2 ==0 and j < len_:\n",
    "        #         val = csum[j+1]-csum[i]\n",
    "        #         if val == (j-i+1)/2:\n",
    "        #             max_ = max(max_, j-i+1)\n",
    "        #         j +=2 \n",
    "        #     if max_ > len_-i+1:\n",
    "        #         break \n",
    "        # return max_ \n",
    "        nums = [1 if i==1 else -1 for i in nums]\n",
    "        recmin = {}\n",
    "        recmax = {}\n",
    "        csum = [0]\n",
    "        for i, v in enumerate(nums):\n",
    "            csum.append(csum[-1]+v) \n",
    "        for i, v in enumerate(csum):\n",
    "            if v not in recmin:\n",
    "                recmax[v] = i \n",
    "                recmin[v] = i\n",
    "            else:\n",
    "                recmin[v] = min(i, recmin[v]) \n",
    "                recmax[v] = max(i, recmax[v])\n",
    "        max_ = 0\n",
    "        for i in recmin.keys():\n",
    "            max_ = max(max_, recmax[i]-recmin[i])\n",
    "\n",
    "        return max_ \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "                  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        sum_pre = {}\n",
    "        pre, ans = 0, 0\n",
    "        for i, num in enumerate(nums):\n",
    "            pre += num * 2 - 1\n",
    "            if pre in sum_pre.keys():\n",
    "                ans = max(ans, i - sum_pre[pre][0])\n",
    "            if pre == 0:\n",
    "                ans = max(ans, i + 1)\n",
    "            if pre in sum_pre.keys():\n",
    "                sum_pre[pre].append(i)\n",
    "            else:\n",
    "                sum_pre[pre] = [i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "        if n == 1:\n",
    "            return 0\n",
    "        \n",
    "        res = 0\n",
    "        mapping = collections.defaultdict(list)\n",
    "        mapping[0] = [-1]\n",
    "        \n",
    "        sum_0 = 0\n",
    "        sum_1 = 0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] == 0:\n",
    "                sum_0 += 1\n",
    "            else:\n",
    "                sum_1 += 1\n",
    "            mapping[sum_1 - sum_0].append(i)\n",
    "            if len(mapping[sum_1 - sum_0]) > 1:\n",
    "                res = max(res, mapping[sum_1 - sum_0][-1] - mapping[sum_1 - sum_0][0])\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        presum=[0]\n",
    "        pos=collections.defaultdict(list)\n",
    "        pos[0]=[-1]\n",
    "        ans=0\n",
    "\n",
    "        for i,x in enumerate(nums):\n",
    "            if x==0:\n",
    "                x=-1\n",
    "            s=presum[-1]+x\n",
    "            presum.append(s)\n",
    "            if pos[s]:\n",
    "                ans=max(ans,i-pos[s][0])\n",
    "            pos[s].append(i)\n",
    "        \n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        dicts = {}\n",
    "        sum = 0 \n",
    "        for i in range(len(nums)):\n",
    "            num = -1 if nums[i] == 0 else nums[i]\n",
    "            sum += num \n",
    "            if sum in dicts:\n",
    "                dicts[sum] = dicts[sum] + [i]\n",
    "            else:\n",
    "                dicts[sum] = [i]\n",
    "        result = 0 \n",
    "        for k, arr in dicts.items():\n",
    "            if k == 0 and arr[-1] + 1 > result:\n",
    "                result = arr[-1] + 1 \n",
    "            if len(arr) >=2 and arr[-1] - arr[0] > result:\n",
    "                result = arr[-1] - arr[0]\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        dicts = {}\n",
    "        sum = 0 \n",
    "        for i in range(len(nums)):\n",
    "            num = -1 if nums[i] == 0 else nums[i]\n",
    "            sum += num \n",
    "            if sum in dicts:\n",
    "                dicts[sum] = dicts[sum] + [i]\n",
    "            else:\n",
    "                dicts[sum] = [i]\n",
    "        result = 0 \n",
    "        for k, arr in dicts.items():\n",
    "            if k == 0 and arr[-1] + 1 > result:\n",
    "                result = arr[-1] + 1 \n",
    "            if len(arr) >=2 and arr[-1] - arr[0] > result:\n",
    "                result = arr[-1] - arr[0]\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        group={'0':[-1]}\n",
    "        sums=0\n",
    "        for index,val in enumerate(nums):\n",
    "            if val==0:\n",
    "                val=-1\n",
    "            sums+=val\n",
    "            if str(sums) in group:\n",
    "                group[str(sums)].append(index)\n",
    "            else:\n",
    "                group[str(sums)]=[index]\n",
    "        max_len=[]\n",
    "        for i in group:\n",
    "            if len(group[i])>=2:\n",
    "                max_len.append(group[i][-1]-group[i][0])\n",
    "        if max_len!=[]:\n",
    "            return max(max_len)\n",
    "        else:\n",
    "            return 0\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        sums = [0]\n",
    "        for num in nums:\n",
    "            sums.append(num + sums[-1])\n",
    "        \n",
    "        n = len(sums)\n",
    "        hash = {}\n",
    "        ans = 0\n",
    "        for i, s in enumerate(sums):\n",
    "            t = 2 * s - i\n",
    "            if t not in hash:\n",
    "                hash[t] = []\n",
    "            if hash[t]:\n",
    "                ans = max(ans, i - hash[t][0])\n",
    "            hash[t].append(i)\n",
    "        return ans\n",
    "\n",
    "# [0, 1, 0, 1 ,1 ,0 ,1 ,0]\n",
    "# [0, 0, 1, 1, 2, 3, 3, 4, 4]\n",
    "\n",
    "\n",
    "#s : 1的个数\n",
    "#i-s: 0的个数\n",
    "#2s - i:  1的个数 - 0的个数\n",
    "#target = 2s - i 多这么多，减去这么多就行了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        sums = []\n",
    "        one = 0\n",
    "        allsum = 0\n",
    "        for i in nums:\n",
    "            one+=i\n",
    "            allsum +=1\n",
    "            sums.append(2*one-allsum)\n",
    "        mpleft = dict()\n",
    "        mpright = dict()\n",
    "        res = 0\n",
    "        for index,i in enumerate(sums):\n",
    "            if mpleft.get(i) is None:\n",
    "                mpleft[i] = index\n",
    "            if i==0:\n",
    "                res = index+1\n",
    "        for index, i in enumerate(sums[::-1]):\n",
    "            if mpright.get(i) is None:\n",
    "                mpright[i] = len(sums)-1-index\n",
    "\n",
    "        for k,v in mpleft.items():\n",
    "            length = mpright[k]-v\n",
    "            res = max(length, res)\n",
    "        return res        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        sums = list()\n",
    "        sum_value = 0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] == 0:\n",
    "                sum_value += -1\n",
    "            else:\n",
    "                sum_value += 1\n",
    "            sums.append(sum_value)\n",
    "        print(sums)\n",
    "        record = defaultdict(list)\n",
    "        record[0].append(-1)\n",
    "        result = 0\n",
    "        for i in range(len(sums)):\n",
    "            if len(record[sums[i]]) != 0:\n",
    "                if i - record[sums[i]][0] > result:\n",
    "                    result = i - record[sums[i]][0]\n",
    "            if len(record[sums[i]]) == 0:\n",
    "                record[sums[i]].append(i)\n",
    "        return result\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        pre_dict = {0: -1,1:1}\n",
    "        nums = [pre_dict[i] for i in nums]\n",
    "\n",
    "        sum_dict = collections.defaultdict(list)\n",
    "        sum_count = 0\n",
    "        sum_dict[0] = [0]\n",
    "        for i in range(len(nums)):\n",
    "            sum_count+=nums[i]\n",
    "            sum_dict[sum_count].append(i+1)\n",
    "\n",
    "        ans = 0\n",
    "        for k in sum_dict.keys():\n",
    "            if len(sum_dict[k])>=2:\n",
    "                ans = max(ans,sum_dict[k][-1]-sum_dict[k][0])\n",
    "\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        res = []\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i,len(s)):\n",
    "                res.append(s[i:j+1]==s[i:j+1][::-1])\n",
    "        return sum(res)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        if_aba = [[0] * (i+1) for i in range(len(s))]\n",
    "        for i in range(len(s)):\n",
    "            if_aba[i][i] = 1\n",
    "            if i-1 >= 0 and s[i] == s[i-1]:\n",
    "                if_aba[i][i-1] = 1\n",
    "        j = 2\n",
    "        while j < len(s):\n",
    "            for i in range(len(s)-j):\n",
    "                if_aba[i+j][i] = if_aba[i+j-1][i+1] if s[i]==s[i+j] else 0\n",
    "            j += 1\n",
    "        return sum([sum(if_aba[i]) for i in range(len(s))])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        dp = [[0]*n for _ in range(n)]\n",
    "        for i in range(n):\n",
    "            dp[i][i] = 1\n",
    "        for i in range(n-1, -1, -1):\n",
    "            for j in range(i, n):\n",
    "                if s[i]!=s[j]:\n",
    "                    dp[i][j] = 0\n",
    "                else:\n",
    "                    if j - i == 0:\n",
    "                        dp[i][j] = 1\n",
    "                    elif j - i ==1:\n",
    "                        dp[i][j] = 1\n",
    "                    else:\n",
    "                        dp[i][j] = dp[i + 1][j - 1]\n",
    "        print(dp)\n",
    "        return sum([sum(i) for i in dp])\n",
    "                        \n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n=len(s)\n",
    "        sons=[[0]*n for i in range(n)]\n",
    "        sub=[]\n",
    "        for i in range(n):\n",
    "            for j in range(i+1):\n",
    "                if i==j:\n",
    "                    #print(1,i,j)\n",
    "                    sons[i][j]=1\n",
    "                    #print(sons)\n",
    "                    sub.append(s[i])\n",
    "                else:\n",
    "                    if s[i]==s[j]:\n",
    "                        if i-j<2:\n",
    "                            #print(2,i,j)\n",
    "                            sons[i][j]=1\n",
    "                            #print(sons)\n",
    "                            sub.append(s[j:i+1])\n",
    "                        else:\n",
    "                            #print(3,i,j)\n",
    "                            sons[i][j]=sons[i-1][j+1]\n",
    "                            #print(sons)\n",
    "\n",
    "        print(sub,sons)\n",
    "        return sum(sum(x) for x in sons)\n",
    "\n",
    "\n",
    "                            \n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        dp = [[0 for _ in range(len(s))] for _ in range(len(s))]\n",
    "        \n",
    "        sum = 0\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            dp[i][i] = 1\n",
    "            sum += 1\n",
    "        \n",
    "        for i in range(1,len(s)):\n",
    "            for j in range(i-1,-1,-1):\n",
    "                if s[i] == s[j]:\n",
    "                    if i - j > 1:\n",
    "                        dp[j][i] = dp[j+1][i-1]\n",
    "                    else:\n",
    "                        dp[j][i] = 1\n",
    "                    if dp[j][i] == 1:\n",
    "                        sum +=1\n",
    "        \n",
    "        print(dp)\n",
    "\n",
    "        return sum\n",
    "                    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        # i~j是否是回文串(d[i][j])\n",
    "        # 1. s[i] == s[j]? \n",
    "        #   1.1 i跟j是否相等; 1.2 s[i]与s[j]是否相等\n",
    "        # 2. d[i+1][j-1]是否是回文串\n",
    "        i = 0\n",
    "        j = len(s)-1\n",
    "        d = [[-1 for i in range(len(s))] for j in range(len(s))]\n",
    "        def check_palindrome(low, high):\n",
    "            if low == high or (high == low+1 and s[high] == s[low]):\n",
    "                return 1\n",
    "            if s[low] == s[high]:\n",
    "                if d[low+1][high-1] == -1:\n",
    "                    d[low+1][high-1] = check_palindrome(low+1, high-1)\n",
    "                return d[low+1][high-1]\n",
    "            return 0\n",
    "        # print(d)\n",
    "        res = 0\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i,len(s)):\n",
    "                if d[i][j] == -1:\n",
    "                    d[i][j] = check_palindrome(i, j)\n",
    "                res += d[i][j]\n",
    "        # print(d)\n",
    "        # res = sum(sum(i) for i in d)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "\n",
    "        n, ans = len(s), 0\n",
    "        substr_map = [[0 for _ in range(n)] for __ in range(n)]\n",
    "        for i in range(n-1, -1, -1):\n",
    "            for j in range(i, n):\n",
    "                if i == j: # 单独字符必定是回文串\n",
    "                    substr_map[i][j] = 1\n",
    "                elif i == j-1: # 相邻字符若相同则是回文串\n",
    "                    substr_map[i][j] = 1 if s[i] == s[j] else 0\n",
    "                else: # 其余情况，只与两端字符相等，且中间是回文串有关\n",
    "                    substr_map[i][j] = substr_map[i+1][j-1] and s[i] == s[j] \n",
    "            ans += sum(substr_map[i])\n",
    "        print(substr_map)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        dp = [[0]*n for _ in range(n)] # dp[i][j]表示字符串s[i:j+1]是否为回文字符串\n",
    "        for i in range(n):\n",
    "            for j in range(i, -1, -1):\n",
    "                if s[i]==s[j]:\n",
    "                    if i-j<=1:\n",
    "                        dp[i][j] = 1\n",
    "                    else:\n",
    "                        dp[i][j] = dp[i-1][j+1]\n",
    "        print(dp)\n",
    "        return sum([dp[i][j] for i in range(n) for j in range(n)])\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import numpy as np\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        arr = np.zeros((n, n))\n",
    "        for i in range(n):\n",
    "            arr[i,i] = 1\n",
    "        for i in range(n-1,-1,-1):\n",
    "            for j in range(i+1,n):\n",
    "                if (s[i] == s[j] and (j - i <= 1 or arr[i + 1][j - 1])):\n",
    "                    arr[i][j] = 1;\n",
    "                    \n",
    "        return int(arr.sum())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import numpy as np\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        dp = np.zeros((n,n))\n",
    "        for i in range(n):\n",
    "            row = n-i-1\n",
    "            for j in range(row,n):\n",
    "                if j == row:\n",
    "                    dp[row][j] = 1\n",
    "                elif j-row == 1 and s[j] == s[row]:\n",
    "                    dp[row][j] = 1\n",
    "                elif j-row > 1 and dp[row+1][j-1] == 1 and s[j] == s[row]:\n",
    "                    dp[row][j] = 1\n",
    "            \n",
    "        return int(np.sum(dp))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        dp = [[0]*len(s) for _ in range(len(s))]\n",
    "        for _ in range(len(s)):\n",
    "            dp[_][_] = 1\n",
    "        \n",
    "        for j in range(len(s)):\n",
    "            for i in range(j):\n",
    "                if s[i] == s[j] and (j-i<2 or dp[i+1][j-1]==1):\n",
    "                    dp[i][j] = 1\n",
    "        \n",
    "        return sum(sum(dp,[]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        import numpy\n",
    "        ma=[[0 for i in range(len(s))] for i in range(len(s))]\n",
    "        for c in range(len(s)):\n",
    "            for j in range(len(s)-c):\n",
    "                jj=j+c\n",
    "                if j==jj:\n",
    "                    ma[j][jj]=1\n",
    "                elif j+1==jj:\n",
    "                    if s[j]==s[jj]:\n",
    "                        ma[j][jj]=1\n",
    "                else:\n",
    "                    if s[j]==s[jj]:\n",
    "                        ma[j][jj]=ma[j+1][jj-1]\n",
    "        su= numpy.sum(ma)\n",
    "        return int(su)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        # def judge(s1):\n",
    "        #     m=len(s1)\n",
    "        #     start,end=0,m-1\n",
    "        #     while start<end:\n",
    "        #         if s1[start]!=s1[end]:\n",
    "        #             return False\n",
    "        #     return True\n",
    "        judge_dict=collections.defaultdict(int)\n",
    "        n=len(s)\n",
    "        s_len=[0]*(n+1)\n",
    "        s_len[1]=n\n",
    "        for i in range(n):\n",
    "            judge_dict[(i,i)]=1\n",
    "            if i<n-1:\n",
    "                judge_dict[(i+1,i)]=1\n",
    "        for i in range(2,n+1):\n",
    "            start=0\n",
    "            end=i-1\n",
    "            while end<n:\n",
    "                if s[start]==s[end] and judge_dict[(start+1,end-1)]==1:\n",
    "                    s_len[i]+=1\n",
    "                    judge_dict[(start,end)]=1\n",
    "                start+=1\n",
    "                end+=1\n",
    "        return sum(s_len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        #入参检查\n",
    "        if len(a) == 0:\n",
    "            return b\n",
    "        elif len(b) == 0:\n",
    "            return a\n",
    "\n",
    "        #补0\n",
    "        zeros = abs(len(a) - len(b))\n",
    "\n",
    "        if len(a) >= len(b):\n",
    "            b = '0' * zeros + b\n",
    "            max_len = len(a)\n",
    "        else:\n",
    "            a = '0' * zeros + a\n",
    "            max_len = len(b)\n",
    "\n",
    "        carry = 0\n",
    "        string = ''\n",
    "        for i in range(1, max_len+1):\n",
    "            print(a[-i], b[-i])\n",
    "            sum = int(a[-i]) + int(b[-i]) + carry\n",
    "            if sum == 0:\n",
    "                string = '0' + string\n",
    "                carry = 0\n",
    "            elif sum == 1:\n",
    "                string = '1' + string\n",
    "                carry = 0\n",
    "            elif sum == 2:\n",
    "                string = '0' + string\n",
    "                carry = 1\n",
    "            else:\n",
    "                string = '1' + string\n",
    "                carry = 1\n",
    "\n",
    "        if carry:\n",
    "            string = '1' + string\n",
    "\n",
    "        return string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        a_ten = self.binary_ten(a)\n",
    "        b_ten = self.binary_ten(b)\n",
    "        sum_ten = a_ten + b_ten\n",
    "        sum_binary = self.ten_binary(sum_ten)\n",
    "        return sum_binary\n",
    "\n",
    "    def binary_ten(self,s ):\n",
    "        length = len(s)\n",
    "        ten_number = 0\n",
    "        for _ in range(length):\n",
    "            ten_number += int(math.pow(2, length-_-1)) * int(s[_])\n",
    "        return ten_number\n",
    "    def ten_binary(self, s):\n",
    "        if s == 0:\n",
    "            return \"0\"\n",
    "        binary_number = \"\"\n",
    "        while s > 0:\n",
    "            binary_number += str(s % 2)\n",
    "            s = s // 2\n",
    "        binary_number = binary_number[::-1]\n",
    "        return binary_number"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        # return bin(int(a,2)+int(b,2))[2:]   bin()将数字转为二进制，int(a,2)将字符串a转为二进制整型  bint()[2:0]去掉\"0b\"取后面的数\n",
    "        sum = []\n",
    "        tmp = 0\n",
    "        a = list(a)\n",
    "        b = list(b)\n",
    "        while(len(a) and len(b)):\n",
    "            pa = int(a.pop())\n",
    "            pb = int(b.pop())\n",
    "            sum1 = str((pa+pb+tmp)%2)\n",
    "            tmp = (pa+pb+tmp) //2\n",
    "            sum.insert(0,sum1)\n",
    "        if len(a):\n",
    "            if tmp == 1:\n",
    "                while(len(a)):\n",
    "                    pa = int(a.pop())\n",
    "                    sum1 = str((tmp+pa)%2)\n",
    "                    tmp = (tmp+pa) // 2\n",
    "                    sum.insert(0,sum1)\n",
    "            else:\n",
    "                a = \"\".join(a)\n",
    "                sum.insert(0,a)\n",
    "        if len(b):\n",
    "            if tmp == 1:\n",
    "                while(len(b)):\n",
    "                    pb = int(b.pop())\n",
    "                    sum1 = str((tmp+pb)%2)\n",
    "                    tmp = (tmp+pb) // 2\n",
    "                    sum.insert(0,sum1)\n",
    "            else:\n",
    "                b = \"\".join(b)\n",
    "                sum.insert(0,b)\n",
    "        if tmp == 1:\n",
    "            sum.insert(0,'1')\n",
    "        sum = \"\".join(sum) \n",
    "        return sum \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(a) - 1, len(b) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            sum = carry\n",
    "            sum += ord(a[i]) - ord(\"0\") if i >= 0 else 0\n",
    "            sum += ord(b[j]) - ord(\"0\") if j >= 0 else 0\n",
    "            res += str(sum % 2)\n",
    "            carry = sum // 2\n",
    "            i, j = i - 1, j - 1\n",
    "        if carry > 0:\n",
    "            res += str(carry)\n",
    "        return res[::-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addBinary(self, a: str, b: str) -> str:\r\n",
    "        s = []\r\n",
    "        c = 0\r\n",
    "        for i in range(max(len(a), len(b))):\r\n",
    "            bit_a = int(a[-i-1]) if i < len(a) else 0\r\n",
    "            bit_b = int(b[-i-1]) if i < len(b) else 0\r\n",
    "            sum = bit_a + bit_b + c\r\n",
    "            s.append(str(sum % 2))\r\n",
    "            c = 1 if sum >= 2 else 0\r\n",
    "        if c == 1:\r\n",
    "            s.append('1')\r\n",
    "        return \"\".join(s[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while True:\n",
    "            sum = 0\n",
    "            while num!=0:\n",
    "                a = num%10\n",
    "                num = num // 10\n",
    "                sum = sum + a\n",
    "            if sum<10:\n",
    "                return sum\n",
    "                break\n",
    "            else:\n",
    "                num = sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        for ele in str(num):\n",
    "            sum = sum + int(ele)\n",
    "        if sum >= 10:\n",
    "            return self.addDigits(sum)\n",
    "        else:\n",
    "            return sum\n",
    "'''\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        total_sum = 0\n",
    "        for digit in str(num):\n",
    "            total_sum += int(digit)\n",
    "        if total_sum >= 10:\n",
    "            return self.addDigits(total_sum)\n",
    "        else:\n",
    "            return total_sum\n",
    "'''\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num:int) -> int:\n",
    "'''\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        num_str = str(num)\n",
    "        for i in num_str:\n",
    "            sum = sum+int(i)\n",
    "        if len(str(sum))==1:\n",
    "            return sum\n",
    "        else:\n",
    "            return self.addDigits(sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        res = num % 9\n",
    "        if res == 0:\n",
    "            res = 9\n",
    "        return res\n",
    "\n",
    "        p = str(num)\n",
    "        while len(p) > 1:\n",
    "            pn = sum([int(i) for i in p])\n",
    "            p = str(pn)\n",
    "        return int(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            num = sum(map(int, str(num)))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "\n",
    "\n",
    "        # 拆分相加函数\n",
    "        def helper(n):\n",
    "            # list = [] \n",
    "            # while n > 0:\n",
    "            #     cur = n % 10\n",
    "            #     list.append(cur)\n",
    "            #     n //= 10\n",
    "            # return sum(list)\n",
    "        # print(helper(num))\n",
    "            sum = 0\n",
    "            while n > 0:\n",
    "                sum += n % 10\n",
    "                n //= 10\n",
    "            return sum\n",
    "\n",
    "        while num >= 10:\n",
    "            num = helper(num)\n",
    "        return num\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        count = 9999999999\n",
    "        while count > 0 and num >= 10:\n",
    "            for i in range(len(str(num))-1):\n",
    "                num = sum(int(char) for char in str(num))\n",
    "                count -= 1\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        s=str(num)\n",
    "        while len(s)!=1:\n",
    "            s=str(sum(int(i) for i in s))\n",
    "        return int(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num > 9:\n",
    "            num = sum(list(map(int, list(str(num)))))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        while(num>0):\n",
    "            sum+=num%10\n",
    "            num=int(num/10)\n",
    "        if sum < 10:\n",
    "            return sum\n",
    "        else:\n",
    "            return self.addDigits(sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        p = str(num)\n",
    "        while len(p) > 1:\n",
    "            pn = sum([int(i) for i in p])\n",
    "            p = str(pn)\n",
    "        return int(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num>=10:\n",
    "            sum=0\n",
    "            while num:\n",
    "                sum+=num%10\n",
    "                num//=10\n",
    "            num=sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while True:\n",
    "            if num//10==0:\n",
    "                return num\n",
    "            num=sum(int(i) for i in list(str(num)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while len(str(num)) != 1:\n",
    "            l = [0 for i in range(0, len(str(num)))]\n",
    "            for i in range(0, len(str(num))):\n",
    "                l[i] = int(str(num)[i])\n",
    "            num = sum(l)\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addDigits(self, num: int) -> int:\r\n",
    "        # if num < 10:\r\n",
    "        #     return num\r\n",
    "        # s = str(num)\r\n",
    "        # res = 0\r\n",
    "        # for c in s: res += int(c)\r\n",
    "        # return self.addDigits(res)\r\n",
    "        # while num >= 10:\r\n",
    "        #     sum = 0\r\n",
    "        #     while num:\r\n",
    "        #         sum += num % 10\r\n",
    "        #         num //= 10\r\n",
    "        #     num = sum\r\n",
    "        # return num\r\n",
    "        return (num - 1) % 9 + 1 if num else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        def jia(num):\n",
    "            sum = 0\n",
    "            while num>0:\n",
    "                sum += num%10\n",
    "                num = num//10\n",
    "            return sum\n",
    "        while num>9:\n",
    "            num = jia(num)\n",
    "        return num\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addDigits(self, num: int) -> int:\r\n",
    "        # if num < 10:\r\n",
    "        #     return num\r\n",
    "        # s = str(num)\r\n",
    "        # res = 0\r\n",
    "        # for c in s: res += int(c)\r\n",
    "        # return self.addDigits(res)\r\n",
    "        while num >= 10:\r\n",
    "            sum = 0\r\n",
    "            while num:\r\n",
    "                sum += num % 10\r\n",
    "                num //= 10\r\n",
    "            num = sum\r\n",
    "        return num\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            num = sum(map(int, str(num)))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num>9:\n",
    "            sum=0\n",
    "            while num:\n",
    "                sum+=num%10\n",
    "                num=num//10\n",
    "            num=sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        rungs.insert(0, 0)\n",
    "        return sum((b-a-1) // dist for a, b in pairwise(rungs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        return sum((b-a-1) // dist for a, b in pairwise(chain([0], rungs)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        return sum((b-a-1) // dist for a, b in pairwise([0] + rungs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1 = len(num1)\n",
    "        n2 = len(num2)\n",
    "        p1 = n1-1\n",
    "        p2 = n2-1\n",
    "        res = ''\n",
    "        temp = 0\n",
    "        while p1 >= 0 or p2 >= 0:\n",
    "            # 两树的和\n",
    "            s1 = '0' if p1 < 0 else num1[p1]\n",
    "            s2 = '0' if p2 < 0 else num2[p2]\n",
    "            two_sum = int(s1)+int(s2)+temp\n",
    "            # 计算进位\n",
    "            temp = two_sum // 10\n",
    "            # 计算余数\n",
    "            left = two_sum % 10\n",
    "            res = str(left)+res\n",
    "            p1 -= 1\n",
    "            p2 -= 1\n",
    "        return '1'+res if temp == 1 else res\n",
    "\n",
    "         \n",
    "\n",
    "             "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        num1 = (len(num2)-len(num1))*'0' + num1\n",
    "        num2 = (len(num1)-len(num2))*'0' + num2\n",
    "        lens = len(num1)\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "        shang = 0\n",
    "        str1 = ''\n",
    "        for i in range(lens):\n",
    "            sum1 = int(num1[i]) + int(num2[i]) + shang\n",
    "            yvshu = sum1 % 10\n",
    "            shang = sum1 // 10\n",
    "            if i != lens -1 :\n",
    "                str1 = str(yvshu) + str1\n",
    "            else:\n",
    "                str1 = str(sum1) + str1\n",
    "        return str1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        plus = 0\n",
    "        res = ''\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        while i >= 0 or j >= 0 or plus > 0:\n",
    "            x = 0\n",
    "            if i >= 0:\n",
    "                x = int(num1[i])\n",
    "            y = 0\n",
    "            if j >= 0:\n",
    "                y = int(num2[j])\n",
    "            sum = x + y + plus\n",
    "            if sum >= 10:\n",
    "                sum = sum % 10\n",
    "                plus = 1\n",
    "            else:\n",
    "                plus = 0\n",
    "            res = str(sum) + res\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        carry, sum = 0, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            sum = n1 + n2 + carry\n",
    "            carry = sum // 10\n",
    "            res = str(sum % 10) + res\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return(\"1\" + res if carry else res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        ans = \"\"\n",
    "        flag = 0\n",
    "        while(i >= 0 or j >= 0 or flag):\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            sum = n1 + n2\n",
    "            \n",
    "            cur = (sum % 10 + flag) % 10\n",
    "            ans += str(cur)\n",
    "            print (cur)\n",
    "\n",
    "            flag = (sum + flag) // 10\n",
    "            print(sum, flag)\n",
    "            i-=1\n",
    "            j-=1\n",
    "        \n",
    "        return ans[::-1] if not flag else '1' + ans[::-1] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # num1 位数\n",
    "        digit1 = len(num1) - 1\n",
    "        # num2 位数\n",
    "        digit2 = len(num2) - 1\n",
    "\n",
    "        # 进位\n",
    "        carry = 0\n",
    "        # sum 存储反向结果\n",
    "        sum = []\n",
    "        # 逆序相加\n",
    "        while carry > 0 or digit1 >= 0 or digit2 >= 0:\n",
    "            # 获取对应位数上的数字\n",
    "            num1_d = int(num1[digit1]) if digit1 >= 0 else 0\n",
    "            num2_d = int(num2[digit2]) if digit2 >= 0 else 0\n",
    "            digit1 -= 1\n",
    "            digit2 -= 1\n",
    "            # 计算结果，存储，进位\n",
    "            num = num1_d+num2_d+carry\n",
    "            sum.append('%d'%(num%10))\n",
    "            carry = num // 10\n",
    "        # 返回计算结果\n",
    "        return \"\".join(sum[::-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # 让 num1 总是更长的一个\n",
    "        if len(num2) > len(num1):\n",
    "            num1, num2 = num2, num1\n",
    "\n",
    "        # 将 num2 用 0 填充，使其与 num1 的长度相同\n",
    "        num2 = num2.zfill(len(num1))\n",
    "\n",
    "        carry = 0  # 进位\n",
    "        result = []\n",
    "\n",
    "        for i in range(len(num1) - 1, -1, -1):\n",
    "            temp_sum = int(num1[i]) + int(num2[i]) + carry\n",
    "            result.append(str(temp_sum % 10))\n",
    "            carry = temp_sum // 10\n",
    "\n",
    "        if carry:  # 如果还有剩余的进位\n",
    "            result.append(str(carry))\n",
    "\n",
    "        return ''.join(result[::-1])  # 反转字符串并合并\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # 反转两个字符串，方便从低位到高位相加\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "\n",
    "        res = [] # 初始化结果字符串\n",
    "        carry = 0 # 初始化进位\n",
    "\n",
    "        # 逐位相加\n",
    "        i= 0\n",
    "        while i <len(num1) or i<len(num2):\n",
    "            # 获取当前位的数字，如果已经超过字符串长度，则默认为0\n",
    "            digit1 = int(num1[i]) if i<len(num1) else 0\n",
    "            digit2 = int(num2[i]) if i<len(num2) else 0\n",
    "            curr_sum = digit1+digit2+carry  # 计算当前位的和，加上进位\n",
    "            carry = curr_sum//10  # 更新进位\n",
    "            res.append(str(curr_sum%10))  # 加入当前值\n",
    "            i += 1\n",
    "        \n",
    "        # 处理最高位的进位\n",
    "        if carry > 0:\n",
    "            res.append(str(carry))\n",
    "        \n",
    "        # 反转结果字符串并返回\n",
    "        res = res[::-1]\n",
    "        return \"\".join(res)\n",
    "        # \"\".join() 是一个字符串方法，用于将一个可迭代对象中的元素连接成一个字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "\n",
    "        # 从最后开始\n",
    "        large = num1 if len(num1) > len(num2) else num2\n",
    "        small = num1 if len(num1) <= len(num2) else num2\n",
    "        large = large[::-1]\n",
    "        small = small[::-1]\n",
    "\n",
    "        carry = 0\n",
    "        output = []\n",
    "        for i in range(len(large)):\n",
    "            l = int(large[i])\n",
    "            s = int(small[i]) if i < len(small) else 0\n",
    "\n",
    "            sum = l + s +carry\n",
    "            output.append(str(sum % 10))\n",
    "            carry = sum // 10\n",
    "        \n",
    "        if carry:\n",
    "            output.append(str(carry))\n",
    "        return \"\".join(output)[::-1]\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # sum = 0\n",
    "        # for i in num:\n",
    "        #     sum = sum * 10 + i\n",
    "        # sum = sum + k\n",
    "        # res = []\n",
    "        # while sum:\n",
    "        #     res.append(sum % 10)\n",
    "        #     sum //= 10\n",
    "        # res = res[::-1]\n",
    "        # return res\n",
    "\n",
    "        i = len(num) - 1\n",
    "        while k:\n",
    "            k += num[i]\n",
    "            num[i],k = k % 10,k // 10\n",
    "            i -= 1\n",
    "\n",
    "            if i < 0 and k:\n",
    "                num.insert(0,0)\n",
    "                i = 0\n",
    "        return num\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "\n",
    "    \tres = []\n",
    "    \ti, carry = len(num) - 1, 0\n",
    "    \twhile i >= 0 or k != 0:\n",
    "        \tx = num[i] if i >= 0 else 0\n",
    "        \ty = k % 10 if k != 0 else 0\n",
    "            \n",
    "        \tsum = x + y + carry\n",
    "        \tres.append(sum % 10)\n",
    "        \tcarry = sum // 10\n",
    "\n",
    "        \ti -= 1\n",
    "        \tk //= 10\n",
    "    \tif carry != 0: res.append(carry)\n",
    "    \treturn res[::-1]\n",
    "    \n",
    "    \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        res = []\n",
    "        k1 = [int(x) for x in str(k)] \n",
    "        n1,n2,add = len(num)-1, len(k1)-1, 0\n",
    "        while n1 >= 0 or n2 >= 0:\n",
    "            print(n1,n2)\n",
    "            x = num[n1] if n1 >=0 else 0\n",
    "            y = k1[n2] if n2 >=0 else 0\n",
    "            sum = x+y+add\n",
    "            res.append(sum % 10)\n",
    "            add = sum // 10\n",
    "            n1 = n1 - 1\n",
    "            n2 = n2-1\n",
    "        if add != 0: res.append(add)\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # str_num = \"\".join([str(n) for n in num])\n",
    "        # sum_num = int(str_num) + k\n",
    "        # list_num = list(str(sum_num))\n",
    "        # return [int(l) for l in list_num]\n",
    "        # ↑ 上述方法在使用 num 长度大于某个值的情况下就会导致溢出错误\n",
    "        # ValueError: Exceeds the limit (4300) for integer string conversion: value has 10000 digits; use sys.set_int_max_str_digits() to increase the limit\n",
    "\n",
    "        num_k = list(str(k))\n",
    "        num_k = [int(i) for i in num_k]\n",
    "\n",
    "        max_len = max(len(num), len(num_k))\n",
    "        num = [0] * (max_len - len(num)) + num\n",
    "        num_k = [0] * (max_len - len(num_k)) + num_k\n",
    "\n",
    "        res = []\n",
    "        jinwei = 0\n",
    "        while num and num_k:\n",
    "            n1 = num.pop(-1)\n",
    "            n2 = num_k.pop(-1)\n",
    "            \n",
    "            yushu = (n1 + n2 + jinwei) % 10\n",
    "            res.insert(0, yushu)\n",
    "            jinwei = (n1 + n2 + jinwei) // 10\n",
    "        \n",
    "        if jinwei > 0:\n",
    "            res.insert(0, jinwei)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        self = num1 + num2;\n",
    "        return self"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1 + num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1+num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1 + num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1+num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "for i,j in product(range(1<<12),range(1<<12)):\n",
    "    i + j \n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1 + num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "     return num1 + num2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1+num2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def sum(self, num1: int, num2: int) -> int:\n",
    "        return num1+num2"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
